Initial repo build

This commit is contained in:
Philip Smart
2022-12-01 09:35:39 +00:00
commit 372b4debad
130 changed files with 78685 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
# -------------------------------------------------------------------------- #
#
# 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.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition
# Date created = 16:29:32 June 24, 2020
#
# -------------------------------------------------------------------------- #
QUARTUS_VERSION = "13.0"
DATE = "16:29:32 September 10, 2021"
# Revisions
PROJECT_REVISION = "tzpuFusionX_MZ2000"

View File

@@ -0,0 +1,243 @@
# -------------------------------------------------------------------------- #
#
# 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.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition
# Date created = 16:29:32 June 24, 2020
#
# -------------------------------------------------------------------------- #
#
# Notes:
#
# 1) The default values for assignments are stored in the file:
# tzpuFusionX.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.
#
# -------------------------------------------------------------------------- #
set_global_assignment -name FAMILY MAX7000AE
set_global_assignment -name DEVICE "EPM7512AETC144-10"
set_global_assignment -name TOP_LEVEL_ENTITY tzpuFusionX_MZ2000
set_global_assignment -name ORIGINAL_QUARTUS_VERSION "13.0 SP1"
set_global_assignment -name PROJECT_CREATION_TIME_DATE "16:29:32 JUNE 24, 2020"
set_global_assignment -name LAST_QUARTUS_VERSION "13.0 SP1"
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR "-1"
set_global_assignment -name EDA_DESIGN_ENTRY_SYNTHESIS_TOOL "<None>"
set_global_assignment -name EDA_INPUT_VCC_NAME VCC -section_id eda_design_synthesis
set_global_assignment -name EDA_INPUT_DATA_FORMAT EDIF -section_id eda_design_synthesis
set_global_assignment -name EDA_SIMULATION_TOOL "ModelSim-Altera (VHDL)"
set_global_assignment -name EDA_OUTPUT_DATA_FORMAT VHDL -section_id eda_simulation
set_global_assignment -name OPTIMIZE_HOLD_TIMING OFF
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING OFF
set_global_assignment -name FITTER_EFFORT "STANDARD FIT"
set_global_assignment -name MAX7000_DEVICE_IO_STANDARD LVTTL
# Z80 Data Bus
# ============
set_location_assignment PIN_81 -to Z80_DATA[0]
set_location_assignment PIN_78 -to Z80_DATA[1]
set_location_assignment PIN_87 -to Z80_DATA[2]
set_location_assignment PIN_100 -to Z80_DATA[3]
set_location_assignment PIN_102 -to Z80_DATA[4]
set_location_assignment PIN_93 -to Z80_DATA[5]
set_location_assignment PIN_94 -to Z80_DATA[6]
set_location_assignment PIN_84 -to Z80_DATA[7]
# Z80 Control signals.
# ====================
set_location_assignment PIN_69 -to Z80_INTn
set_location_assignment PIN_70 -to Z80_NMIn
set_location_assignment PIN_71 -to Z80_HALTn
set_location_assignment PIN_68 -to Z80_MREQn
set_location_assignment PIN_65 -to Z80_IORQn
set_location_assignment PIN_67 -to Z80_RDn
set_location_assignment PIN_66 -to Z80_WRn
set_location_assignment PIN_63 -to Z80_BUSAKn
set_location_assignment PIN_62 -to Z80_WAITn
set_location_assignment PIN_61 -to Z80_BUSRQn
set_location_assignment PIN_79 -to Z80_RFSHn
set_location_assignment PIN_60 -to Z80_M1n
set_location_assignment PIN_56 -to Z80_RESETn
set_location_assignment PIN_101 -to Z80_CLK
# Z80 Address Bus
# ===============
set_location_assignment PIN_80 -to Z80_ADDR[0]
set_location_assignment PIN_90 -to Z80_ADDR[1]
set_location_assignment PIN_83 -to Z80_ADDR[2]
set_location_assignment PIN_86 -to Z80_ADDR[3]
set_location_assignment PIN_88 -to Z80_ADDR[4]
set_location_assignment PIN_91 -to Z80_ADDR[5]
set_location_assignment PIN_92 -to Z80_ADDR[6]
set_location_assignment PIN_96 -to Z80_ADDR[7]
set_location_assignment PIN_97 -to Z80_ADDR[8]
set_location_assignment PIN_98 -to Z80_ADDR[9]
set_location_assignment PIN_99 -to Z80_ADDR[10]
set_location_assignment PIN_110 -to Z80_ADDR[11]
set_location_assignment PIN_108 -to Z80_ADDR[12]
set_location_assignment PIN_107 -to Z80_ADDR[13]
set_location_assignment PIN_106 -to Z80_ADDR[14]
set_location_assignment PIN_103 -to Z80_ADDR[15]
# SOM SPI
# =======
set_location_assignment PIN_32 -to VSOM_SPI_CSn
set_location_assignment PIN_31 -to VSOM_SPI_CLK
set_location_assignment PIN_30 -to VSOM_SPI_MOSI
set_location_assignment PIN_29 -to VSOM_SPI_MISO
# SOM Parallel Bus
# ================
set_location_assignment PIN_41 -to VSOM_DATA_OUT[0]
set_location_assignment PIN_40 -to VSOM_DATA_OUT[1]
set_location_assignment PIN_39 -to VSOM_DATA_OUT[2]
set_location_assignment PIN_38 -to VSOM_DATA_OUT[3]
set_location_assignment PIN_37 -to VSOM_DATA_OUT[4]
set_location_assignment PIN_36 -to VSOM_DATA_OUT[5]
set_location_assignment PIN_35 -to VSOM_DATA_OUT[6]
set_location_assignment PIN_34 -to VSOM_DATA_OUT[7]
set_location_assignment PIN_132 -to VSOM_HBYTE
# SOM Reserved signals.
# =====================
set_location_assignment PIN_21 -to VSOM_RSV[1]
# SOM Control Signals
# ===================
set_location_assignment PIN_28 -to VSOM_READY
set_location_assignment PIN_18 -to VSOM_LTSTATE
set_location_assignment PIN_27 -to VSOM_BUSRQ
set_location_assignment PIN_26 -to VSOM_BUSACK
set_location_assignment PIN_19 -to VSOM_INT
set_location_assignment PIN_22 -to VSOM_NMI
set_location_assignment PIN_25 -to VSOM_WAIT
set_location_assignment PIN_23 -to VSOM_RESET
set_location_assignment PIN_16 -to PM_RESET
# VGA_Palette Control
# ===================
set_location_assignment PIN_133 -to VGA_R[7]
set_location_assignment PIN_137 -to VGA_R[8]
set_location_assignment PIN_140 -to VGA_R[9]
set_location_assignment PIN_134 -to VGA_G[7]
set_location_assignment PIN_138 -to VGA_G[8]
set_location_assignment PIN_141 -to VGA_G[9]
set_location_assignment PIN_136 -to VGA_B[8]
set_location_assignment PIN_139 -to VGA_B[9]
# VGA Control Signals
# ===================
set_location_assignment PIN_142 -to VGA_PXL_CLK
set_location_assignment PIN_14 -to VGA_DISPEN
set_location_assignment PIN_12 -to VGA_VSYNCn
set_location_assignment PIN_11 -to VGA_HSYNCn
set_location_assignment PIN_82 -to VGA_COLR
set_location_assignment PIN_109 -to VGA_CSYNCn
set_location_assignment PIN_143 -to VGA_BLANKn
# CRT Control Signals
# ===================
set_location_assignment PIN_15 -to MONO_PXL_CLK
set_location_assignment PIN_114 -to MONO_BLANKn
set_location_assignment PIN_113 -to MONO_CSYNCn
set_location_assignment PIN_116 -to MONO_RSV
# CRT Lower Chrominance Control
# =============================
set_location_assignment PIN_1 -to MONO_R[0]
set_location_assignment PIN_6 -to MONO_R[1]
set_location_assignment PIN_10 -to MONO_R[2]
set_location_assignment PIN_2 -to MONO_G[0]
set_location_assignment PIN_7 -to MONO_G[1]
set_location_assignment PIN_9 -to MONO_G[2]
set_location_assignment PIN_5 -to MONO_B[1]
set_location_assignment PIN_8 -to MONO_B[2]
# MUX Control Signals
# ===================
set_location_assignment PIN_72 -to VIDEO_SRC
set_location_assignment PIN_74 -to MONO_VIDEO_SRC
set_location_assignment PIN_77 -to AUDIO_SRC_L
set_location_assignment PIN_75 -to AUDIO_SRC_R
# Mainboard Reset Signals
# =======================
#set_location_assignment PIN_127 -to CPU_RESETn
set_location_assignment PIN_122 -to MB_RESETn
set_location_assignment PIN_111 -to MB_IPLn
# USB Power Control
# =================
set_location_assignment PIN_55 -to VBUS_EN
# Clocks
# ======
#set_location_assignment PIN_125 -to CPU_CLK
set_location_assignment PIN_128 -to CLK_50M
# Unused ports
# ============
#set_location_assignment PIN_42 -to
#set_location_assignment PIN_43 -to
#set_location_assignment PIN_44 -to
#set_location_assignment PIN_45 -to
#set_location_assignment PIN_112 -to
#set_location_assignment PIN_131 -to
#set_location_assignment PIN_117 -to
#set_location_assignment PIN_118 -to
#set_location_assignment PIN_119 -to
#set_location_assignment PIN_120 -to
#set_location_assignment PIN_121 -to
#set_location_assignment PIN_25 -to
#set_location_assignment PIN_53 -to
#set_location_assignment PIN_128 -to
#set_location_assignment PIN_47 -to
#set_location_assignment PIN_54 -to
#set_location_assignment PIN_127 -to
#set_location_assignment PIN_125 -to
#set_location_assignment PIN_48 -to
#set_location_assignment PIN_46 -to
#set_location_assignment PIN_49 -to
set_global_assignment -name VHDL_FILE ../tzpuFusionX_Toplevel.vhd
set_global_assignment -name VHDL_FILE ../tzpuFusionX_pkg.vhd
set_global_assignment -name VHDL_FILE ../tzpuFusionX.vhd
set_global_assignment -name SDC_FILE tzpuFusionX_MZ2000_constraints.sdc
set_global_assignment -name VHDL_INPUT_VERSION VHDL_2008
set_global_assignment -name VHDL_SHOW_LMF_MAPPING_MESSAGES OFF
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS OFF
set_global_assignment -name MAX7000_OPTIMIZATION_TECHNIQUE AREA
set_global_assignment -name AUTO_RESOURCE_SHARING OFF
set_global_assignment -name PRE_MAPPING_RESYNTHESIS OFF
set_global_assignment -name USE_LOGICLOCK_CONSTRAINTS_IN_BALANCING OFF
set_global_assignment -name INFER_RAMS_FROM_RAW_LOGIC OFF
set_global_assignment -name AUTO_LCELL_INSERTION ON
set_global_assignment -name CDF_FILE output_files/tzpuFusionX_MZ2000.cdf

View File

@@ -0,0 +1,324 @@
## Generated SDC file "tzpuFusionX.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.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition"
## DATE "Fri Jun 26 22:10:05 2020"
##
## DEVICE "EPM7160STC100-10"
##
#**************************************************************
# Time Information
#**************************************************************
set_time_format -unit ns -decimal_places 3
#**************************************************************
# Create Clock
#**************************************************************
# Standard mainboard clock. If using tzpuFusionX on a different host then set to the host frequency.
create_clock -name {Z80_CLK} -period 250.000 -waveform { 0.000 125.000 } [get_ports { Z80_CLK }]
# For 50MHz crystal.
create_clock -name {CLK_50M} -period 20.000 -waveform { 0.000 10.000 } [ get_ports { CLK_50M }]
# For SPI CSn
#create_clock -name {VSOM_SPI_CSn} -period 200.000 -waveform { 160.000 40.000 } [ get_ports { VSOM_SPI_CSn }]
# For SPI CLK
create_clock -name {VSOM_SPI_CLK} -period 14.000 -waveform { 0.000 7.000 } [ get_ports { VSOM_SPI_CLK }]
# For basic board with oscillator.
#create_clock -name {CTLCLK} -period 20.000 -waveform { 0.000 10.000 } [ get_ports { CTLCLK }]
#create_clock -name {cpld512:cpldl512Toplevel|CTLCLKi} -period 280.000 -waveform { 0.000 140.000 } [ get_keepers {cpld512:cpldl512Toplevel|CTLCLKi} ]
##create_clock -name {Z80_CLK} -period 50.000 -waveform { 0.000 25.000 } [get_ports { CTLCLK }]
#**************************************************************
# Create Generated Clock
#**************************************************************
#**************************************************************
# Set Clock Latency
#**************************************************************
#**************************************************************
# Set Clock Uncertainty
#**************************************************************
#derive_clock_uncertainty
#**************************************************************
# Set Input Delay
#**************************************************************
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CTL_MBSEL}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CTL_BUSRQn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CTL_WAITn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {SYS_BUSRQn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {SYS_WAITn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_ADDR[*]}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_HI_ADDR[*]}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {VZ80_ADDR[*]}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_BUSACKn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_DATA[*]}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_HALTn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_IORQn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_M1n}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_MREQn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_RESETn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_RFSHn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_WRn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_RDn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {R_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {G_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {B_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {COLR_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CSYNC_IN}]
##set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CVIDEO_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {HSYNC_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {VSYNC_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {VZ80_DATA[*]}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_MREQn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_IORQn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_WRn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_RDn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_M1n}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_BUSACKn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_INTn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_NMIn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_WAITn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VWAITn_A21_V_CSYNC}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A20_RFSHn_V_HSYNC}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A19_HALTn_V_VSYNC}]
#**************************************************************
# Set Output Delay
#**************************************************************
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {CTL_BUSACKn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {CTL_HALTn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {CTL_M1n}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {CTL_RFSHn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {RAM_CSn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {RAM_CS2n}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {RAM_OEn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {RAM_WEn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {SVCREQn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {SYS_BUSACKn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_BUSRQn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_DATA[*]}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_ADDR[*]}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_HI_ADDR[*]}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_RA_ADDR[*]}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_WAITn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_MREQn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_CLK}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_ADDR[*]}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_DATA[*]}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_CLK}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_MREQn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_IORQn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_RDn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_WRn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_M1n}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VIDEO_RDn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VIDEO_WRn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A18_INTn_V_R}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_BUSRQn_V_G}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A16_WAITn_V_B}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A17_NMIn_V_COLR}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VWAITn_A21_V_CSYNC}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A20_RFSHn_V_HSYNC}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A19_HALTn_V_VSYNC}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_HALTn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_RFSHn}]
# For K64F
#set_output_delay -add_delay -clock [get_clocks {CTLCLK}] 5.000 [get_ports {Z80_CLK}]
# For basic board with oscillator.
#set_output_delay -add_delay -clock [get_clocks {cpld512:cpldl512Toplevel|CTLCLKi}] 5.000 [get_ports {Z80_CLK}]
#**************************************************************
# Set Max Delay
#**************************************************************
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_HALTn} 30.000
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_IORQn} 30.000
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_M1n} 30.000
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_RDn} 30.000
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_WRn} 30.000
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_RFSHn} 30.000
#set_max_delay -from [get_ports {VZ80_A19_HALTn_V_VSYNC}] -to {Z80_HALTn} 30.000
#set_max_delay -from [get_ports {VZ80_IORQn}] -to {Z80_IORQn} 30.000
#set_max_delay -from [get_ports {VZ80_MREQn}] -to {Z80_IORQn} 30.000
#set_max_delay -from [get_ports {VZ80_M1n}] -to {Z80_M1n} 30.000
#set_max_delay -from [get_ports {VZ80_RDn}] -to {Z80_RDn} 30.000
#set_max_delay -from [get_ports {VZ80_WRn}] -to {Z80_WRn} 30.000
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_HALTn} 40.000
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_RFSHn} 40.000
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_IORQn} 40.000
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_M1n} 30.000
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_RDn} 30.000
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_WRn} 30.000
#set_max_delay -from [get_ports {VZ80_A20_RFSHn_V_HSYNC}] -to {Z80_RFSHn} 30.000
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_HALTn} 30.000
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_IORQn} 30.000
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_M1n} 30.000
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_RDn} 30.000
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_WRn} 30.000
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_RFSHn} 30.000
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_HALTn}] 45.000
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_IORQn}] 30.000
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_M1n}] 30.000
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_RDn}] 30.000
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_RFSHn}] 45.000
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_WRn}] 30.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_HALTn}] 45.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_IORQn}] 50.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_M1n}] 40.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_RDn}] 40.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_WRn}] 40.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_RFSHn}] 45.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_HALTn}] 60.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_IORQn}] 45.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_M1n}] 40.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_RDn}] 40.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_WRn}] 40.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_RFSHn}] 60.000
#**************************************************************
# Set Min Delay
#**************************************************************
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_HALTn} 1.000
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_IORQn} 1.000
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_M1n} 1.000
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_RDn} 1.000
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_WRn} 1.000
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_RFSHn} 1.000
#set_min_delay -from [get_ports {VZ80_A19_HALTn_V_VSYNC}] -to {Z80_HALTn} 1.000
#set_min_delay -from [get_ports {VZ80_IORQn}] -to {Z80_IORQn} 1.000
#set_min_delay -from [get_ports {VZ80_MREQn}] -to {Z80_IORQn} 1.000
#set_min_delay -from [get_ports {VZ80_M1n}] -to {Z80_M1n} 1.000
#set_min_delay -from [get_ports {VZ80_RDn}] -to {Z80_RDn} 1.000
#set_min_delay -from [get_ports {VZ80_WRn}] -to {Z80_WRn} 1.000
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_HALTn} 1.000
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_RFSHn} 1.000
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_IORQn} 1.000
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_M1n} 1.000
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_RDn} 1.000
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_WRn} 1.000
#set_min_delay -from [get_ports {VZ80_A20_RFSHn_V_HSYNC}] -to {Z80_RFSHn} 1.000
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_HALTn} 1.000
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_IORQn} 1.000
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_M1n} 1.000
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_RDn} 1.000
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_WRn} 1.000
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_RFSHn} 1.000
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_HALTn}] 1.000
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_IORQn}] 1.000
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_M1n}] 1.000
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_RDn}] 1.000
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_RFSHn}] 1.000
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_WRn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_HALTn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_IORQn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_M1n}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_RDn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_WRn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_RFSHn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_HALTn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_IORQn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_M1n}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_RDn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_WRn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_RFSHn}] 1.000
#**************************************************************
# Set Clock Groups
#**************************************************************
#**************************************************************
# Set False Path
#**************************************************************
# For K64F
#set_false_path -from [get_clocks {CTLCLK}] -to [get_clocks {SYSCLK}]
#set_false_path -from [get_clocks {SYSCLK}] -to [get_clocks {CTLCLK}]
# For basic board with oscillator.
#set_false_path -from [get_clocks {cpld512:cpldl512Toplevel|CTLCLKi}] -to [get_clocks {SYSCLK}]
#set_false_path -from [get_clocks {cpld512:cpldl512Toplevel|CTLCLKi}] -to [get_clocks {CTLCLK}]
#set_false_path -from [get_clocks {SYSCLK}] -to [get_clocks {cpld512:cpldl512Toplevel|CTLCLKi}]
#set_false_path -from [get_clocks {SYSCLK}] -to [get_clocks {CTLCLK}]
# For both configurations.
#set_false_path -from {cpld512:cpldl512Toplevel|KEY_SUBSTITUTE} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|MZ80B_VRAM_HI_ADDR} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|MZ80B_VRAM_LO_ADDR} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|MODE_VIDEO_MZ80B} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|GRAM_PAGE_ENABLE} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#**************************************************************
# Set Multicycle Path
#**************************************************************
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CTL_BUSRQni} -to {cpld512:cpldl512Toplevel|CTLCLK_Q} -setup -end 2
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CTL_BUSRQni} -to {cpld512:cpldl512Toplevel|CTLCLK_Q} -hold -end 1
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CTL_BUSRQni} -to {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -setup -end 2
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CTL_BUSRQni} -to {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -hold -end 1
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -setup -end 2
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -hold -end 1
#**************************************************************
# Set Maximum Delay
#**************************************************************
#**************************************************************
# Set Minimum Delay
#**************************************************************
#**************************************************************
# Set Input Transition
#**************************************************************

View File

@@ -0,0 +1,985 @@
-------------------------------------------------------------------------------------------------------
--
-- Name: tzpuFusionX.vhd
-- Version: MZ-2000
-- Created: June 2020
-- Author(s): Philip Smart
-- Description: tzpuFusionX CPLD logic definition file.
-- This module contains the definition of the tzpuFusionX project plus enhancements
-- for the MZ-2000.
--
-- Credits:
-- Copyright: (c) 2018-22 Philip Smart <philip.smart@net2net.org>
--
-- History: Oct 2022 - Initial write for the MZ-2000.
--
---------------------------------------------------------------------------------------------------------
-- 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->.
---------------------------------------------------------------------------------------------------------
library ieee;
library pkgs;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use work.tzpuFusionX_pkg.all;
entity cpld512 is
generic (
SPI_CLK_POLARITY : std_logic := '0'
);
port (
-- Z80 Address Bus
Z80_ADDR : inout std_logic_vector(15 downto 0);
-- Z80 Data Bus
Z80_DATA : inout std_logic_vector(7 downto 0);
-- Z80 Control signals.
Z80_BUSRQn : in std_logic;
Z80_BUSAKn : out std_logic;
Z80_INTn : in std_logic;
Z80_IORQn : inout std_logic;
Z80_MREQn : inout std_logic;
Z80_NMIn : in std_logic;
Z80_RDn : inout std_logic;
Z80_WRn : inout std_logic;
Z80_RESETn : in std_logic; -- Host CPU Reset signal, also CPLD reset.
Z80_HALTn : out std_logic;
Z80_WAITn : in std_logic;
Z80_M1n : inout std_logic;
Z80_RFSHn : inout std_logic;
-- SOM Control Signals
VSOM_SPI_CLK : in std_logic; -- SOM SPI Channel 0 Clock.
VSOM_SPI_MOSI : in std_logic; -- MOSI Input.
VSOM_SPI_MISO : out std_logic; -- MISO Output.
VSOM_SPI_CSn : in std_logic; -- Enable.
-- SOM Parallel Bus.
VSOM_DATA_OUT : out std_logic_vector(7 downto 0); -- Address/Data bus for CPLD control registers.
VSOM_HBYTE : in std_logic; -- Parallel Bus High (1)/Low (0) byte.
VSOM_READY : out std_logic; -- FSM Ready (1), Busy (0)
VSOM_LTSTATE : out std_logic; -- Last T-State in current cycle, 1 = active.
VSOM_BUSRQ : out std_logic; -- Host device requesting Z80 Bus.
VSOM_BUSACK : out std_logic; -- Host device granted Z80 Bus
VSOM_INT : out std_logic; -- Z80 INT signal
VSOM_NMI : out std_logic; -- Z80 NMI signal
VSOM_WAIT : out std_logic; -- Z80 WAIT signal
VSOM_RESET : out std_logic; -- Z80 RESET signal
VSOM_RSV : out std_logic_vector(1 downto 1); -- Reserved pins.
-- SOM Control Signals
PM_RESET : out std_logic; -- Reset SOM
-- VGA_Palette Control
VGA_R : in std_logic_vector(9 downto 7); -- Signals used for detecting blank or no video output.
VGA_G : in std_logic_vector(9 downto 7);
VGA_B : in std_logic_vector(9 downto 8);
-- VGA Control Signals
VGA_PXL_CLK : in std_logic; -- VGA Pixel clock for DAC conversion.
VGA_DISPEN : in std_logic; -- Displayed Enabled (SOM video output).
VGA_VSYNCn : in std_logic; -- SOM VSync.
VGA_HSYNCn : in std_logic; -- SOM HSync.
VGA_COLR : out std_logic; -- COLR colour carrier frequency.
VGA_CSYNCn : out std_logic; -- VGA Composite Sync.
VGA_BLANKn : out std_logic; -- VGA Blank detected.
-- CRT Control Signals
MONO_PXL_CLK : out std_logic; -- Mono CRT pixel clock for DAC conversion.
MONO_BLANKn : out std_logic; -- Mono CRT Blank (no active pixel) detection.
MONO_CSYNCn : out std_logic; -- Mono CRT composite sync.
MONO_RSV : out std_logic;
-- CRT Lower Chrominance Control
MONO_R : out std_logic_vector(2 downto 0); -- Signals to fine tune Red level of monochrome chrominance.
MONO_G : out std_logic_vector(2 downto 0); -- Signals to fine tune Green level of monochrome chrominance.
MONO_B : out std_logic_vector(2 downto 1); -- Signals to fine tune Blue level of monochrome chrominance.
-- MUX Control Signals
VIDEO_SRC : out std_logic; -- Select video source, Mainboard or SOM.
MONO_VIDEO_SRC : out std_logic; -- Select crt video source, Mainboard or SOM.
AUDIO_SRC_L : out std_logic; -- Select Audio Source Left Channel, Mainboard or SOM.
AUDIO_SRC_R : out std_logic; -- Select Audio Source Right Channel, Mainboard or SOM.
-- Mainboard Reset Signals
MB_RESETn : in std_logic; -- Motherboard Reset pressed.
MB_IPLn : in std_logic; -- Motherboard IPL pressed.
-- USB Power Control
VBUS_EN : out std_logic; -- USB Enable Power Output
-- Clocks.
Z80_CLK : in std_logic; -- Host CPU Clock
CLK_50M : in std_logic -- 50MHz oscillator.
);
end entity;
architecture rtl of cpld512 is
-- Finite State Machine states.
type SOMFSMState is
(
IdleCycle,
FetchCycle,
FetchCycle_11,
FetchCycle_20,
FetchCycle_21,
FetchCycle_30,
RefreshCycle,
RefreshCycle_11,
RefreshCycle_20,
RefreshCycle_21,
RefreshCycle_3,
WriteCycle,
WriteCycle_11,
WriteCycle_20,
WriteCycle_21,
WriteCycle_30,
WriteCycle_31,
ReadCycle,
ReadCycle_11,
ReadCycle_20,
ReadCycle_21,
ReadCycle_30,
ReadCycle_31,
WriteIOCycle,
WriteIOCycle_11,
WriteIOCycle_20,
WriteIOCycle_21,
WriteIOCycle_30,
WriteIOCycle_31,
WriteIOCycle_40,
WriteIOCycle_41,
ReadIOCycle,
ReadIOCycle_11,
ReadIOCycle_20,
ReadIOCycle_21,
ReadIOCycle_30,
ReadIOCycle_31,
ReadIOCycle_40,
ReadIOCycle_41,
HaltCycle,
BusReqCycle
);
-- CPU Interface internal signals.
signal Z80_BUSRQni : std_logic;
signal Z80_INTni : std_logic;
signal Z80_IORQni : std_logic;
signal Z80_MREQni : std_logic;
signal Z80_NMIni : std_logic;
signal Z80_RDni : std_logic;
signal Z80_WRni : std_logic;
signal Z80_HALTni : std_logic;
signal Z80_M1ni : std_logic;
signal Z80_RFSHni : std_logic;
signal Z80_DATAi : std_logic_vector(7 downto 0);
signal Z80_BUSRQ_ACKni : std_logic;
-- Internal CPU state control.
signal CPU_ADDR : std_logic_vector(15 downto 0) := (others => '0');
signal CPU_DATA_IN : std_logic_vector(7 downto 0) := (others => '0');
signal CPU_DATA_OUT : std_logic_vector(7 downto 0) := (others => '0');
signal CPU_DATA_EN : std_logic;
-- Clocks.
signal CLK_25Mi : std_logic := '0';
-- Reset control
signal PM_RESETi : std_logic := '1';
signal VSOM_RESETni : std_logic := '1';
-- Refresh control.
signal FSM_STATE : SOMFSMState := IdleCycle;
signal NEW_SPI_CMD : std_logic := '0';
signal VCPU_CS_EDGE : std_logic_vector(1 downto 0) := "11";
signal AUTOREFRESH_CNT : integer range 0 to 7;
signal FSM_STATUS : std_logic := '0';
signal FSM_CHECK_WAIT : std_logic := '0';
signal FSM_WAIT_ACTIVE : std_logic := '0';
signal RFSH_STATUS : std_logic := '0';
signal REFRESH_ADDR : std_logic_vector(7 downto 0);
signal IPAR : std_logic_vector(7 downto 0);
signal AUTOREFRESH : std_logic;
-- Clock edge detection and flagging.
signal Z80_CLKi : std_logic;
signal Z80_CLK_LAST : std_logic_vector(1 downto 0);
signal Z80_CLK_RE : std_logic;
signal Z80_CLK_FE : std_logic;
signal Z80_CLK_TGL : std_logic;
signal CPU_T_STATE_SET : integer range 0 to 5;
signal CPU_LAST_T_STATE : std_logic := '0';
-- SPI Slave interface.
signal SPI_SHIFT_EN : std_logic;
signal SPI_TX_SREG : std_logic_vector(6 downto 0); -- TX Shift Register
signal SPI_RX_SREG : std_logic_vector(7 downto 0); -- RX Shift Register
signal SPI_TX_DATA : std_logic_vector(31 downto 0); -- Data to transmit.
signal SPI_RX_DATA : std_logic_vector(31 downto 0); -- Data received.
signal SPI_BIT_CNT : integer range 0 to 16; -- Count of bits tx/rx'd.
signal SPI_FRAME_CNT : integer range 0 to 4; -- Number of frames received (8bit chunks).
-- SPI Command interface.
signal SOM_CMD : std_logic_vector(7 downto 0) := (others => '0');
signal SPI_NEW_DATA : std_logic;
signal SPI_PROCESSING : std_logic;
signal SPI_CPU_ADDR : std_logic_vector(15 downto 0) := (others => '0');
signal SPI_CPU_DATA : std_logic_vector(7 downto 0) := (others => '0');
-- Test modes.
signal SPI_LOOPBACK_TEST : std_logic := '0';
-- Video/Audio control
signal VIDEO_SRCi : std_logic := '0';
signal MONO_VIDEO_SRCi : std_logic := '0';
signal AUDIO_SRC_Li : std_logic := '0';
signal AUDIO_SRC_Ri : std_logic := '0';
signal VBUS_ENi : std_logic := '1';
function to_std_logic(L: boolean) return std_logic is
begin
if L then
return('1');
else
return('0');
end if;
end function to_std_logic;
begin
-- System RESET.
--
-- Multiple reset sources, Z80_RESETn, MB_IPLn, MB_RESETn. On the MZ-2000, MB_IPLn is a full reset where all the gate array
-- registers are reset and the memory map resets to the power on state for initial program loading. MB_RESETn is a warm
-- restart for loaded programs, ie. keeps the programmed memory state but resets the Z80 which automatically executes the
-- loaded program. Like the MZ-700, we trigger on Z80_RESETn after having sampled the MB_IPLn and MB_RESETn states to decide
-- on any extra actions needed within the CPLD and the signals are forwarded onto the SOM so it too can take the correct
-- reset path.
--
-- If the external reset switch is pressed, a Z80_RESETn is invoked sending the signal low for approx 30ms.
-- On the first edge the VSOM_RESETn signal is set which allows the SOM to see it and the Z80 application to enter a reset state.
-- On the second edge, if occurring within 1 second of the first, the PM_RESET signal to the SOM is triggered, held low for 1 second,
-- forcing the SOM to reboot.
SYSRESET: process( Z80_CLKi, Z80_RESETn )
variable timer1 : integer range 0 to 354000 := 0;
variable timer100 : integer range 0 to 10 := 0;
variable timerPMReset : integer range 0 to 10 := 0;
variable resetCount : integer range 0 to 3 := 0;
variable cpuResetEdge : std_logic := '1';
begin
-- Synchronous on the HOST Clock.
if(rising_edge(Z80_CLKi)) then
-- If the PM Reset timer is active, count down and on expiry release the SOM PM_RESET line.
if(timerPMReset = 0 and PM_RESETi = '1') then
PM_RESETi <= '0';
end if;
-- If the VSOM_RESETni is active after reset timer expiry, cancel the RESET state.
if(timerPMReset = 0 and VSOM_RESETni = '0') then
VSOM_RESETni <= '1';
end if;
-- Each time the reset button is pressed, count the edges.
if(Z80_RESETn = '0' and cpuResetEdge = '1' and (resetCount = 0 or timer100 > 5)) then
resetCount := resetCount + 1;
VSOM_RESETni <= '0';
timerPMReset := 5;
timer100 := 0;
-- If there are 2 or more reset signals in a given period it means a SOM reset is required.
if(resetCount >= 2) then
PM_RESETi <= '1';
timerPMReset := 10;
resetCount := 0;
end if;
end if;
-- 100ms interval.
if(timer1 = 354000) then
timer100 := timer100 + 1;
if(timer100 >= 10) then
timer100 := 0;
resetCount := 0;
end if;
if(timerPMReset > 0) then
timerPMReset := timerPMReset - 1;
end if;
end if;
timer1 := timer1 - 1;
cpuResetEdge := Z80_RESETn;
end if;
end process;
-- Create Mono DAC Clock based on primary clock.
MONOCLK: process( CLK_50M )
begin
if(rising_edge(CLK_50M)) then
CLK_25Mi <= not CLK_25Mi;
end if;
end process;
-- SPI Slave input. Receive command and data from the SOM.
SPI_INPUT : process(VSOM_SPI_CLK)
begin
-- SPI_CLK_POLARITY='0' => falling edge; SPI_CLK_POLARITY='1' => rising edge
if(VSOM_SPI_CLK'event and VSOM_SPI_CLK = SPI_CLK_POLARITY) then
if(VSOM_SPI_CSn = '0') then
SPI_RX_SREG <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
-- End of frame then store the data prior to next bit arrival.
-- Convert to Little Endian, same as SOM.
if(SPI_SHIFT_EN = '1' and SPI_FRAME_CNT = 1 and SPI_BIT_CNT = 0) then
SPI_RX_DATA(7 downto 0) <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
elsif(SPI_SHIFT_EN = '1' and SPI_FRAME_CNT = 2 and SPI_BIT_CNT = 0) then
SPI_RX_DATA(15 downto 8) <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
elsif(SPI_SHIFT_EN = '1' and SPI_FRAME_CNT = 3 and SPI_BIT_CNT = 0) then
SPI_RX_DATA(23 downto 16) <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
elsif(SPI_SHIFT_EN = '1' and SPI_FRAME_CNT = 4 and SPI_BIT_CNT = 0) then
SPI_RX_DATA(31 downto 24) <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
end if;
end if;
end if;
end process;
-- SPI Slave output. Return the current data set as selected by the input signals XACT.
SPI_OUTPUT : process(VSOM_SPI_CLK,VSOM_SPI_CSn,SPI_TX_DATA)
begin
if(VSOM_SPI_CSn = '1') then
SPI_SHIFT_EN <= '0';
SPI_BIT_CNT <= 15;
-- SPI_CLK_POLARITY='0' => falling edge; SPI_CLK_POLARITY='1' => risinge edge
elsif(VSOM_SPI_CLK'event and VSOM_SPI_CLK = not SPI_CLK_POLARITY) then
SPI_SHIFT_EN <= '1';
if(SPI_BIT_CNT > 0) then
SPI_BIT_CNT <= SPI_BIT_CNT - 1;
end if;
VSOM_SPI_MISO <= SPI_TX_SREG(6);
SPI_TX_SREG <= SPI_TX_SREG(5 downto 0) & '0';
-- First clock after CS goes active, load up the data to be sent to the SOM.
if(SPI_SHIFT_EN = '0' or SPI_BIT_CNT = 0) then
if(SPI_LOOPBACK_TEST = '1') then
VSOM_SPI_MISO<= SPI_RX_SREG(7);
SPI_TX_SREG <= SPI_RX_SREG(6 downto 0);
elsif(SPI_SHIFT_EN = '0') then
SPI_FRAME_CNT<= 1;
VSOM_SPI_MISO<= SPI_TX_DATA(7);
SPI_TX_SREG <= SPI_TX_DATA(6 downto 0);
elsif(SPI_FRAME_CNT = 1) then
SPI_FRAME_CNT<= 2;
VSOM_SPI_MISO<= SPI_TX_DATA(15);
SPI_TX_SREG <= SPI_TX_DATA(14 downto 8);
elsif(SPI_FRAME_CNT = 2) then
SPI_FRAME_CNT<= 3;
VSOM_SPI_MISO<= SPI_TX_DATA(23);
SPI_TX_SREG <= SPI_TX_DATA(22 downto 16);
else
-- Increment frame count for each word received. We handle 8bit (1 frame), 16bit (2 frames) or 32bit (4 frames) reception.
SPI_FRAME_CNT<= 4;
VSOM_SPI_MISO<= SPI_TX_DATA(31);
SPI_TX_SREG <= SPI_TX_DATA(30 downto 24);
end if;
SPI_BIT_CNT <= 7;
end if;
end if;
end process;
SPI_REGISTER : process(Z80_RESETn, VSOM_SPI_CSn, SPI_FRAME_CNT)
begin
if(Z80_RESETn = '0') then
VIDEO_SRCi <= '0';
VGA_BLANKn <= '1';
VBUS_ENi <= '1';
MONO_VIDEO_SRCi <= '1';
AUDIO_SRC_Li <= '0';
AUDIO_SRC_Ri <= '0';
AUTOREFRESH <= '0';
SPI_LOOPBACK_TEST <= '0';
SOM_CMD <= (others => '0');
SPI_CPU_ADDR <= (others => '0');
SPI_NEW_DATA <= '0';
-- On rising edge of SPI CSn a new data packet from the SOM has arrived and in the shift register SPI_RX_SREG.
-- The variable SPI_FRAME_CNT indicates which byte (frame) in a 32bit word has been transmitted. This allows
-- for 8bit, 16bit and 32bit transmissions.
-- The packet is formatted as follows:
--
-- < SPI_FRAME_CNT=4 >< SPI_FRAME=3 > < SPI_FRAME_CNT=2 >< SPI_FRAME_CNT=1>
-- < 16bit Z80 Address > < Z80 Data ><Command=00..80>
-- 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
--
-- < > < Data ><Command=F0..FF>
-- 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
--
elsif(VSOM_SPI_CSn'event and VSOM_SPI_CSn = '1') then
-- Command is always located in the upper byte of frame 1.
SOM_CMD <= SPI_RX_DATA(7 downto 0);
-- Toggle flag to indicate new data arrived.
SPI_NEW_DATA <= not SPI_NEW_DATA;
-- Process the command. Some commands require the FSM, others can be serviced immediately.
case SPI_RX_DATA(7 downto 0) is
-- Z80XACT(0..15): Setup data and address as provided then execute FSM.
when X"10" | X"11" | X"12" | X"13" | X"14" | X"15" | X"16" | X"17" | -- Fetch
X"18" | X"19" | X"1A" | X"1B" | X"1C" | X"1D" | X"1E" | X"1F" | -- Write
X"20" | X"21" | X"22" | X"23" | X"24" | X"25" | X"26" | X"27" | -- Read
X"28" | X"29" | X"2A" | X"2B" | X"2C" | X"2D" | X"2E" | X"2F" | -- WriteIO
X"30" | X"31" | X"32" | X"33" | X"34" | X"35" | X"36" | X"37" | -- ReadIO
X"38" | X"39" | X"3A" | X"3B" | X"3C" | X"3D" | X"3E" | X"3F" | --
X"40" | X"41" | X"42" | X"43" | X"44" | X"45" | X"46" | X"47" | --
X"48" | X"49" | X"4A" | X"4B" | X"4C" | X"4D" | X"4E" | X"4F" =>
-- Direct address set.
if(SPI_FRAME_CNT = 4) then
SPI_CPU_ADDR <= SPI_RX_DATA(31 downto 16);
else
-- if(SPI_CPU_ADDR >= X"D010" and SPI_CPU_ADDR < X"D020") then
-- SPI_CPU_ADDR <= std_logic_vector(X"D020" + unsigned(SPI_RX_DATA(2 downto 0)));
-- else
SPI_CPU_ADDR <= std_logic_vector(unsigned(SPI_CPU_ADDR) + unsigned(SPI_RX_DATA(2 downto 0)));
-- end if;
end if;
if(SPI_FRAME_CNT > 1) then
SPI_CPU_DATA <= SPI_RX_DATA(15 downto 8);
end if;
-- SETSIGSET1: Set control lines directly.
when X"F0" =>
VIDEO_SRCi <= SPI_RX_DATA(8);
MONO_VIDEO_SRCi <= SPI_RX_DATA(9);
AUDIO_SRC_Li <= SPI_RX_DATA(10);
AUDIO_SRC_Ri <= SPI_RX_DATA(11);
VBUS_ENi <= SPI_RX_DATA(12);
VGA_BLANKn <= not SPI_RX_DATA(13);
-- Enable auto refresh DRAM cycle.
when X"F1" =>
AUTOREFRESH <= '1';
-- Disable auto refresh DRAM cycle.
when X"F2" =>
AUTOREFRESH <= '0';
-- SETLOOPBACK: Enable loopback test mode.
when X"FE" =>
SPI_LOOPBACK_TEST<= '1';
-- No action, called to retrieve status.
when X"00" | X"FF" =>
when others =>
end case;
end if;
end process;
-- Process to detect the Z80 Clock edges. Each edge is used to recreate the Z80 external signals.
--
Z80CLK: process( CLK_50M, Z80_CLKi, Z80_RESETn )
begin
if(Z80_RESETn = '0') then
Z80_CLK_RE <= '1';
Z80_CLK_FE <= '1';
Z80_CLK_TGL <= '1';
elsif(rising_edge(CLK_50M)) then
-- Default is to clear the signals, only active for 1 clock period.
Z80_CLK_RE <= '0';
Z80_CLK_FE <= '0';
Z80_CLK_TGL <= '0';
-- Rising Edge.
if(Z80_CLKi = '1' and Z80_CLK_LAST = "00") then
Z80_CLK_RE <= '1';
-- Toggle on rising edge is delayed by one clock to allow time for command to be decoded.
elsif(Z80_CLKi = '1' and Z80_CLK_LAST = "01") then
Z80_CLK_TGL <= '1';
-- Falling Edge.
elsif(Z80_CLKi = '0' and Z80_CLK_LAST = "11") then
Z80_CLK_FE <= '1';
Z80_CLK_TGL <= '1';
end if;
Z80_CLK_LAST <= Z80_CLK_LAST(0) & Z80_CLKi;
end if;
end process;
-- SOM Finite State Machine.
--
-- A command processor, based on an FSM concept, to process requested commands, ie. Z80 Write, Z80 Read etc.
-- The external signal SOM_CMD_EN, when set, indicates a new command available in SOM_CMD.
--
SOMFSM: process( CLK_50M, Z80_CLKi, Z80_RESETn )
begin
if(Z80_RESETn = '0') then
Z80_IORQni <= '1';
Z80_MREQni <= '1';
Z80_RDni <= '1';
Z80_WRni <= '1';
Z80_HALTni <= '1';
Z80_M1ni <= '1';
Z80_RFSHni <= '1';
Z80_BUSRQ_ACKni <= '1';
FSM_CHECK_WAIT <= '0';
FSM_WAIT_ACTIVE <= '0';
FSM_STATUS <= '0';
FSM_STATE <= IdleCycle;
RFSH_STATUS <= '0';
CPU_DATA_EN <= '0';
CPU_DATA_IN <= (others => '0');
REFRESH_ADDR <= (others => '0');
AUTOREFRESH_CNT <= 7;
IPAR <= (others => '0');
NEW_SPI_CMD <= '0';
VCPU_CS_EDGE <= "11";
SPI_PROCESSING <= '0';
elsif(rising_edge(CLK_50M)) then
-- Bus request mechanism. If an externel Bus Request comes in and the FSM is idle, run the Bus Request command which
-- suspends processing and tri-states the bus.
if(Z80_BUSRQn = '0' and Z80_BUSRQ_ACKni = '1' and FSM_STATE = IdleCycle) then
FSM_STATE <= BusReqCycle;
end if;
if(Z80_BUSRQn = '1' and Z80_BUSRQ_ACKni = '0' and FSM_STATE = IdleCycle) then
Z80_BUSRQ_ACKni <= '1';
end if;
-- New command, set flag as the signal is only 1 clock wide.
if(SPI_LOOPBACK_TEST = '0' and VSOM_SPI_CSn = '1' and VCPU_CS_EDGE = "01") then
NEW_SPI_CMD <= '1';
end if;
-- Whenever we return to Idle or just prior to Refresh from a Fetch cycle set all control signals to default.
if(FSM_STATE = IdleCycle or FSM_STATE = RefreshCycle) then
CPU_DATA_EN <= '0';
Z80_MREQni <= '1';
Z80_IORQni <= '1';
Z80_RDni <= '1';
Z80_WRni <= '1';
Z80_M1ni <= '1';
FSM_STATUS <= '0';
Z80_RFSHni <= '1';
-- Auto DRAM refresh cycles. When enabled, every 7 host clock cycles, a 2 cycle refresh period commences.
-- This will be overriden if the SPI receives a new command.
--
if AUTOREFRESH = '1' and FSM_STATE = IdleCycle then
AUTOREFRESH_CNT <= AUTOREFRESH_CNT - 1;
if(AUTOREFRESH_CNT = 0) then
FSM_STATE <= RefreshCycle_3;
end if;
end if;
end if;
-- If new command has been given and the FSM enters idle state, load up new command for processing.
if(NEW_SPI_CMD = '1' and FSM_STATE = IdleCycle and Z80_CLK_RE = '1') then
NEW_SPI_CMD <= '0';
-- Store new address and data for this command.
CPU_ADDR <= SPI_CPU_ADDR;
if(SPI_CPU_DATA /= CPU_DATA_OUT) then
CPU_DATA_OUT <= SPI_CPU_DATA;
end if;
-- Process the SOM command. The SPI_REGISTER executes non FSM commands and stores FSM
-- data prior to this execution block, which fires 1 cycle later on the same control clock.
-- If the command is not for the FSM then the READY mechanism is held for one
-- further cycle before going inactive.
case SOM_CMD is
when X"10" | X"11" | X"12" | X"13" | X"14" | X"15" | X"16" | X"17" =>
-- Initiate a Fetch Cycle.
FSM_STATE <= FetchCycle;
when X"18" | X"19" | X"1A" | X"1B" | X"1C" | X"1D" | X"1E" | X"1F" =>
-- Set the Z80 data bus value and initiate a Write Cycle.
FSM_STATE <= WriteCycle;
when X"20" | X"21" | X"22" | X"23" | X"24" | X"25" | X"26" | X"27" =>
-- Initiate a Read Cycle.
FSM_STATE <= ReadCycle;
when X"28" | X"29" | X"2A" | X"2B" | X"2C" | X"2D" | X"2E" | X"2F" =>
-- Set the Z80 data bus value and initiate an IO Write Cycle.
-- The SOM should set 15:8 to the B register value.
FSM_STATE <= WriteIOCycle;
when X"30" | X"31" | X"32" | X"33" | X"34" | X"35" | X"36" | X"37" =>
-- Initiate a Read IO Cycle.
FSM_STATE <= ReadIOCycle;
when X"50" =>
-- Register a Halt state.
FSM_STATE <= HaltCycle;
when X"51" =>
-- Initiate a refresh cycle.
FSM_STATE <= RefreshCycle_3;
when X"E0" =>
-- Initiate a Halt Cycle.
FSM_STATE <= HaltCycle;
-- Set the Refresh Address register.
when X"E1" =>
REFRESH_ADDR <= CPU_DATA_OUT;
-- Set the Interrupt Page Address Register.
when X"E2" =>
IPAR <= CPU_DATA_OUT;
when others =>
end case;
-- Toggle the processing flag to negate the new data flag. Used to indicate device is busy.
if(SPI_NEW_DATA /= SPI_PROCESSING) then
SPI_PROCESSING <= not SPI_PROCESSING;
end if;
-- FSM Status bit. When processing a command it is set, cleared when idle. Used by SOM to determine command completion.
FSM_STATUS <= '1';
end if;
-- Refresh status bit. Indicates a Refresh cycle is under way.
if FSM_STATE = RefreshCycle or FSM_STATE = RefreshCycle_11 or FSM_STATE = RefreshCycle_20 or FSM_STATE = RefreshCycle_21 or FSM_STATE = RefreshCycle_3 then
RFSH_STATUS <= '1';
else
RFSH_STATUS <= '0';
end if;
-- If we are in a WAIT sampling 1/2 cycle and wait goes active, set the state so we repeat the full clock cycle by winding back 2 places.
if(FSM_CHECK_WAIT = '1' and Z80_WAITn = '0' and Z80_CLK_TGL = '0') then
FSM_WAIT_ACTIVE <= '1';
end if;
-- On each Z80 edge we advance the FSM to recreate the Z80 external signal transactions.
if(Z80_CLK_TGL = '1') then
-- The FSM advances to the next stage on each Z80 edge unless in Idle state.
if(FSM_STATE /= IdleCycle) then
FSM_STATE <= SOMFSMState'val(SOMFSMState'POS(FSM_STATE)+1);
end if;
-- Half cycle expired so we dont check the Z80 wait again.
FSM_CHECK_WAIT <= '0';
FSM_WAIT_ACTIVE <= '0';
-- FSM to implement all the required Z80 cycles.
--
case FSM_STATE is
when IdleCycle =>
CPU_LAST_T_STATE <= '1';
-- FSM_STATE <= IdleCycle;
-----------------------------
-- Z80 Fetch Cycle.
-----------------------------
when FetchCycle =>
Z80_M1ni <= '0';
when FetchCycle_11 =>
Z80_M1ni <= '0';
Z80_MREQni <= '0';
Z80_RDni <= '0';
when FetchCycle_20 =>
FSM_CHECK_WAIT <= '1';
when FetchCycle_21 =>
if(Z80_WAITn = '0' or FSM_WAIT_ACTIVE = '1') then
FSM_STATE <= FetchCycle_20;
end if;
when FetchCycle_30 =>
-- To meet the timing diagrams, just after Rising edge on T3 clear signals. Data wont be available until
-- a short period before the falling edge of T3 (could be an MZ-2000 design restriction or the Z80 timing diagrams are a bit out).
FSM_STATE <= RefreshCycle;
-----------------------------
-- Z80 Refresh Cycle.
-----------------------------
when RefreshCycle =>
-- Latch data from mainboard.
CPU_DATA_IN <= Z80_DATA;
FSM_STATUS <= '0';
Z80_RFSHni <= '0';
when RefreshCycle_11 =>
-- Falling edge of T3 activates the MREQ line.
Z80_MREQni <= '0';
when RefreshCycle_20 =>
when RefreshCycle_21 =>
Z80_MREQni <= '1';
REFRESH_ADDR(6 downto 0) <= REFRESH_ADDR(6 downto 0) + 1;
FSM_STATE <= IdleCycle;
when RefreshCycle_3 =>
Z80_RFSHni <= '0';
FSM_STATE <= RefreshCycle_11;
-----------------------------
-- Z80 Write Cycle.
-----------------------------
when WriteCycle =>
when WriteCycle_11 =>
Z80_MREQni <= '0';
CPU_DATA_EN <= '1';
when WriteCycle_20 =>
FSM_CHECK_WAIT <= '1';
when WriteCycle_21 =>
Z80_WRni <= '0';
if(Z80_WAITn = '0' or FSM_WAIT_ACTIVE = '1') then
FSM_STATE <= WriteCycle_20;
end if;
when WriteCycle_30 =>
when WriteCycle_31 =>
FSM_STATUS <= '0';
Z80_MREQni <= '1';
Z80_WRni <= '1';
FSM_STATE <= IdleCycle;
-----------------------------
-- Z80 Read Cycle.
-----------------------------
when ReadCycle =>
when ReadCycle_11 =>
Z80_MREQni <= '0';
Z80_RDni <= '0';
when ReadCycle_20 =>
FSM_CHECK_WAIT <= '1';
when ReadCycle_21 =>
if(Z80_WAITn = '0' or FSM_WAIT_ACTIVE = '1') then
FSM_STATE <= ReadCycle_20;
end if;
when ReadCycle_30 =>
when ReadCycle_31 =>
-- Latch data from mainboard.
CPU_DATA_IN <= Z80_DATA;
FSM_STATUS <= '0';
FSM_STATE <= IdleCycle;
-----------------------------
-- Z80 IO Write Cycle.
-----------------------------
when WriteIOCycle =>
when WriteIOCycle_11 =>
CPU_DATA_EN <= '1';
when WriteIOCycle_20 =>
Z80_IORQni <= '0';
Z80_WRni <= '0';
when WriteIOCycle_21 =>
when WriteIOCycle_30 =>
FSM_CHECK_WAIT <= '1';
when WriteIOCycle_31 =>
if(Z80_WAITn = '0' or FSM_WAIT_ACTIVE = '1') then
FSM_STATE <= WriteIOCycle_20;
end if;
when WriteIOCycle_40 =>
when WriteIOCycle_41 =>
FSM_STATUS <= '0';
Z80_IORQni <= '1';
Z80_WRni <= '1';
FSM_STATE <= IdleCycle;
-----------------------------
-- Z80 IO Read Cycle.
-----------------------------
when ReadIOCycle =>
when ReadIOCycle_11 =>
when ReadIOCycle_20 =>
Z80_IORQni <= '0';
Z80_RDni <= '0';
when ReadIOCycle_21 =>
when ReadIOCycle_30 =>
FSM_CHECK_WAIT <= '1';
when ReadIOCycle_31 =>
if(Z80_WAITn = '0' or FSM_WAIT_ACTIVE = '1') then
FSM_STATE <= ReadIOCycle_20;
end if;
when ReadIOCycle_40 =>
when ReadIOCycle_41 =>
-- Latch data from mainboard.
CPU_DATA_IN <= Z80_DATA;
FSM_STATUS <= '0';
-- IORQ/RD are deactivated at idle giving 1 clock to latch the data in.
FSM_STATE <= IdleCycle;
-----------------------------
-- Halt Request.
-----------------------------
when HaltCycle =>
Z80_HALTni <= '0';
FSM_STATUS <= '0';
FSM_STATE <= IdleCycle;
-----------------------------
-- Z80 Bus Request.
-----------------------------
when BusReqCycle =>
Z80_BUSRQ_ACKni <= '0';
FSM_STATE <= IdleCycle;
when others =>
FSM_STATE <= IdleCycle;
end case;
end if;
VCPU_CS_EDGE <= VCPU_CS_EDGE(0) & VSOM_SPI_CSn;
end if;
end process;
Z80_CLKi <= not Z80_CLK;
-- CPU Interface tri-state control based on acknowledged bus request.
Z80_ADDR <= IPAR & REFRESH_ADDR when Z80_RFSHni = '0'
else
CPU_ADDR when Z80_BUSRQ_ACKni = '1'
else
(others => 'Z');
Z80_DATA <= CPU_DATA_OUT when Z80_BUSRQ_ACKni = '1' and CPU_DATA_EN = '1'
else
(others => 'Z');
-- Z80_DATAi <= Z80_DATA when Z80_RDn = '0'
-- else (others => '1');
Z80_RDn <= Z80_RDni when Z80_BUSRQ_ACKni = '1'
else 'Z';
Z80_WRn <= Z80_WRni when Z80_BUSRQ_ACKni = '1'
else 'Z';
Z80_M1n <= Z80_M1ni when Z80_BUSRQ_ACKni = '1'
else 'Z';
Z80_RFSHn <= Z80_RFSHni when Z80_BUSRQ_ACKni = '1'
else 'Z';
Z80_MREQn <= Z80_MREQni when Z80_BUSRQ_ACKni = '1'
else 'Z';
Z80_IORQn <= Z80_IORQni when Z80_BUSRQ_ACKni = '1'
else 'Z';
Z80_BUSAKn <= Z80_BUSRQ_ACKni;
-- CPU Interface single state output.
Z80_HALTn <= Z80_HALTni;
-- CPU Interface single state input.
Z80_NMIni <= Z80_NMIn;
Z80_INTni <= Z80_INTn;
Z80_BUSRQni <= Z80_BUSRQn;
-- SOM Reset.
PM_RESET <= PM_RESETi;
-- SOM to CPLD Interface.
VSOM_DATA_OUT <= CPU_DATA_IN when VSOM_HBYTE = '1'
else
FSM_STATUS & RFSH_STATUS & Z80_BUSRQ_ACKni & Z80_BUSRQni & Z80_INTni & Z80_NMIni & Z80_WAITn & Z80_RESETn when VSOM_HBYTE = '0'
else
(others => '0');
-- Loopback test, echo what was received.
SPI_TX_DATA <= SPI_RX_DATA when SPI_LOOPBACK_TEST = '1'
else
--CPU_ADDR & SOM_CMD & FSM_STATUS & RFSH_STATUS & std_logic_vector(to_unsigned(SOMFSMState'POS(FSM_STATE), 6));
CPU_ADDR & CPU_DATA_IN & FSM_STATUS & RFSH_STATUS & Z80_BUSRQ_ACKni & Z80_BUSRQni & Z80_INTni & Z80_NMIni & Z80_WAITn & Z80_RESETn;
-- Signal mirrors.
VSOM_READY <= '0' when FSM_STATUS='1' or SPI_NEW_DATA /= SPI_PROCESSING
else '1'; -- FSM Ready (1), Busy (0)
VSOM_LTSTATE <= '1' when CPU_LAST_T_STATE = '1' -- Last T-State in current cycle.
else '0';
VSOM_BUSRQ <= not Z80_BUSRQn; -- Host device requesting Z80 Bus.
VSOM_BUSACK <= not Z80_BUSRQ_ACKni; -- Host device granted Z80 Bus
VSOM_INT <= not Z80_INTn; -- Z80 INT signal
VSOM_NMI <= not Z80_NMIn; -- Z80 NMI signal
VSOM_WAIT <= not Z80_WAITn; -- Z80 WAIT signal
VSOM_RESET <= not VSOM_RESETni; -- Z80 RESET signal
VSOM_RSV <= (others => '0'); -- Reserved pins.
-- Video/Audio control signals.
VIDEO_SRC <= VIDEO_SRCi;
MONO_VIDEO_SRC <= MONO_VIDEO_SRCi;
AUDIO_SRC_L <= AUDIO_SRC_Li;
AUDIO_SRC_R <= AUDIO_SRC_Ri;
-- USB Power Supply enable.
VBUS_EN <= VBUS_ENi;
-- Monochrome output is based on the incoming VGA to give the best chrominance levels.
MONO_R <= VGA_R;
MONO_G <= VGA_G;
MONO_B <= VGA_B;
-- Blanking is active when all colour signals are at 0. The DAC converts values in range 4v .. 5v to adjust chrominance
-- but true off can obly be achieved by bringing the signal value to 0v which is achieved by a Mux activated with this blanking signal.
MONO_BLANKn <= '0' when VGA_R = "000" and VGA_G = "000" and VGA_B = "000"
else '1';
-- Generate composite sync.
VGA_CSYNCn <= VGA_HSYNCn xor not VGA_VSYNCn;
MONO_CSYNCn <= not VGA_HSYNCn xor not VGA_VSYNCn;
-- DAC clocks.
--VGA_PXL_CLK <= CLK_50M;
MONO_PXL_CLK <= VGA_PXL_CLK;
end architecture;

View File

@@ -0,0 +1,222 @@
---------------------------------------------------------------------------------------------------------
--
-- Name: tzpuFusionX_Toplevel.vhd
-- Version: MZ-2000
-- Created: June 2020
-- Author(s): Philip Smart
-- Description: tzpuFusionX CPLD Top Level module.
--
-- This module contains the basic pin definition of the CPLD<->logic needed in the
-- project which targets the MZ-2000 host.
--
-- Credits:
-- Copyright: (c) 2018-22 Philip Smart <philip.smart@net2net.org>
--
-- History: June 2020 - Snapshot taken from the MZ80A version of the tranZPUter SW-700 source.
--
---------------------------------------------------------------------------------------------------------
-- 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.
--
-- along with this program. If not, see <http:--www.gnu.org-licenses->.
---------------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.tzpuFusionX_pkg.all;
library altera;
use altera.altera_syn_attributes.all;
entity tzpuFusionX_MZ2000 is
port (
-- Z80 Address Bus
Z80_ADDR : inout std_logic_vector(15 downto 0);
-- Z80 Data Bus
Z80_DATA : inout std_logic_vector(7 downto 0);
-- Z80 Control signals.
Z80_BUSRQn : in std_logic;
Z80_BUSAKn : out std_logic;
Z80_INTn : in std_logic;
Z80_IORQn : inout std_logic;
Z80_MREQn : inout std_logic;
Z80_NMIn : in std_logic;
Z80_RDn : inout std_logic;
Z80_WRn : inout std_logic;
Z80_RESETn : in std_logic; -- Host CPU Reset signal, also CPLD reset.
Z80_HALTn : out std_logic;
Z80_WAITn : in std_logic;
Z80_M1n : inout std_logic;
Z80_RFSHn : inout std_logic;
-- SOM SPI
VSOM_SPI_CSn : in std_logic; -- SPI Slave Select
VSOM_SPI_CLK : in std_logic; -- SPI Clock
VSOM_SPI_MOSI : in std_logic; -- SPI Master Output Slave Input
VSOM_SPI_MISO : out std_logic; -- SPI Master Input Slave Output
-- SOM Parallel Bus.
VSOM_DATA_OUT : out std_logic_vector(7 downto 0); -- Address/Data bus for CPLD control registers.
VSOM_HBYTE : in std_logic; -- Parallel Bus High (1)/Low (0) byte.
VSOM_READY : out std_logic; -- FSM Ready (1), Busy (0)
VSOM_LTSTATE : out std_logic; -- Last T-State in current cycle, 1 = active.
VSOM_BUSRQ : out std_logic; -- Host device requesting Z80 Bus.
VSOM_BUSACK : out std_logic; -- Host device granted Z80 Bus
VSOM_INT : out std_logic; -- Z80 INT signal
VSOM_NMI : out std_logic; -- Z80 NMI signal
VSOM_WAIT : out std_logic; -- Z80 WAIT signal
VSOM_RESET : out std_logic; -- Z80 RESET signal
VSOM_RSV : out std_logic_vector(1 downto 1); -- Reserved pins.
-- SOM Control Signals
PM_RESET : out std_logic; -- Reset SOM
-- VGA_Palette Control
VGA_R : in std_logic_vector(9 downto 7); -- Signals used for detecting blank or no video output.
VGA_G : in std_logic_vector(9 downto 7);
VGA_B : in std_logic_vector(9 downto 8);
-- VGA Control Signals
VGA_PXL_CLK : in std_logic; -- VGA Pixel clock for DAC conversion.
VGA_DISPEN : in std_logic; -- Displayed Enabled (SOM video output).
VGA_VSYNCn : in std_logic; -- SOM VSync.
VGA_HSYNCn : in std_logic; -- SOM HSync.
VGA_COLR : out std_logic; -- COLR colour carrier frequency.
VGA_CSYNCn : out std_logic; -- VGA Composite Sync.
VGA_BLANKn : out std_logic; -- VGA Blank detected.
-- CRT Control Signals
MONO_PXL_CLK : out std_logic; -- Mono CRT pixel clock for DAC conversion.
MONO_BLANKn : out std_logic; -- Mono CRT Blank (no active pixel) detection.
MONO_CSYNCn : out std_logic; -- Mono CRT composite sync.
MONO_RSV : out std_logic;
-- CRT Lower Chrominance Control
MONO_R : out std_logic_vector(2 downto 0); -- Signals to fine tune Red level of monochrome chrominance.
MONO_G : out std_logic_vector(2 downto 0); -- Signals to fine tune Green level of monochrome chrominance.
MONO_B : out std_logic_vector(2 downto 1); -- Signals to fine tune Blue level of monochrome chrominance.
-- MUX Control Signals
VIDEO_SRC : out std_logic; -- Select video source, Mainboard or SOM.
MONO_VIDEO_SRC : out std_logic; -- Select crt video source, Mainboard or SOM.
AUDIO_SRC_L : out std_logic; -- Select Audio Source Left Channel, Mainboard or SOM.
AUDIO_SRC_R : out std_logic; -- Select Audio Source Right Channel, Mainboard or SOM.
-- Mainboard Reset Signals
MB_RESETn : in std_logic; -- Motherboard Reset pressed.
MB_IPLn : in std_logic; -- Motherboard IPL pressed.
-- USB Power Control
VBUS_EN : out std_logic; -- USB Enable Power Output
-- Clocks.
Z80_CLK : in std_logic; -- Host CPU Clock
CLK_50M : in std_logic -- 50MHz oscillator.
);
END entity;
architecture rtl of tzpuFusionX_MZ2000 is
begin
cpldl512Toplevel : entity work.cpld512
generic map (
SPI_CLK_POLARITY => '0'
)
port map
(
-- Z80 Address Bus
Z80_ADDR => Z80_ADDR,
-- Z80 Data Bus
Z80_DATA => Z80_DATA,
-- Z80 Control signals.
Z80_BUSRQn => Z80_BUSRQn,
Z80_BUSAKn => Z80_BUSAKn,
Z80_INTn => Z80_INTn,
Z80_IORQn => Z80_IORQn,
Z80_MREQn => Z80_MREQn,
Z80_NMIn => Z80_NMIn,
Z80_RDn => Z80_RDn,
Z80_WRn => Z80_WRn,
Z80_RESETn => Z80_RESETn,
Z80_HALTn => Z80_HALTn,
Z80_WAITn => Z80_WAITn,
Z80_M1n => Z80_M1n,
Z80_RFSHn => Z80_RFSHn,
-- SOM SPI
VSOM_SPI_CSn => VSOM_SPI_CSn, -- SPI Slave Select
VSOM_SPI_CLK => VSOM_SPI_CLK, -- SPI Clock
VSOM_SPI_MOSI => VSOM_SPI_MOSI, -- SPI Master Output Slave Input
VSOM_SPI_MISO => VSOM_SPI_MISO, -- SPI Master Input Slave Output
-- SOM Parallel Bus.
VSOM_DATA_OUT => VSOM_DATA_OUT, -- Address/Data bus for CPLD control registers.
VSOM_HBYTE => VSOM_HBYTE, -- Parallel Bus High (1)/Low (0) byte.
VSOM_READY => VSOM_READY, -- FSM Ready (1), Busy (0)
VSOM_LTSTATE => VSOM_LTSTATE, -- Last T-State in current cycle.
VSOM_BUSRQ => VSOM_BUSRQ, -- Host device requesting Z80 Bus.
VSOM_BUSACK => VSOM_BUSACK, -- Host device granted Z80 Bus
VSOM_INT => VSOM_INT, -- Z80 INT signal
VSOM_NMI => VSOM_NMI, -- Z80 NMI signal
VSOM_WAIT => VSOM_WAIT, -- Z80 WAIT signal
VSOM_RESET => VSOM_RESET, -- Z80 RESET signal
VSOM_RSV => VSOM_RSV, -- Reserved pins.
-- SOM Control Signals
PM_RESET => PM_RESET, -- Reset SOM
-- VGA_Palette Control
VGA_R => VGA_R, -- Signals used for detecting blank or no video output.
VGA_G => VGA_G,
VGA_B => VGA_B,
-- VGA Control Signals
VGA_PXL_CLK => VGA_PXL_CLK, -- VGA Pixel clock for DAC conversion.
VGA_DISPEN => VGA_DISPEN, -- Displayed Enabled (SOM video output).
VGA_VSYNCn => VGA_VSYNCn, -- SOM VSync.
VGA_HSYNCn => VGA_HSYNCn, -- SOM HSync.
VGA_COLR => VGA_COLR, -- COLR colour carrier frequency.
VGA_CSYNCn => VGA_CSYNCn, -- VGA Composite Sync.
VGA_BLANKn => VGA_BLANKn, -- VGA Blank detected.
-- CRT Control Signals
MONO_PXL_CLK => MONO_PXL_CLK, -- Mono CRT pixel clock for DAC conversion.
MONO_BLANKn => MONO_BLANKn, -- Mono CRT Blank (no active pixel) detection.
MONO_CSYNCn => MONO_CSYNCn, -- Mono CRT composite sync.
MONO_RSV => MONO_RSV,
-- CRT Lower Chrominance Control
MONO_R => MONO_R, -- Signals to fine tune Red level of monochrome chrominance.
MONO_G => MONO_G, -- Signals to fine tune Green level of monochrome chrominance.
MONO_B => MONO_B, -- Signals to fine tune Blue level of monochrome chrominance.
-- MUX Control Signals
VIDEO_SRC => VIDEO_SRC, -- Select video source, Mainboard or SOM.
MONO_VIDEO_SRC => MONO_VIDEO_SRC, -- Select crt video source, Mainboard or SOM.
AUDIO_SRC_L => AUDIO_SRC_L, -- Select Audio Source Left Channel, Mainboard or SOM.
AUDIO_SRC_R => AUDIO_SRC_R, -- Select Audio Source Right Channel, Mainboard or SOM.
-- Mainboard Reset Signals=> MONO_R,
MB_RESETn => MB_RESETn, -- Motherboard Reset pressed.
MB_IPLn => MB_IPLn, -- Motherboard IPL pressed.
-- USB Power Control
VBUS_EN => VBUS_EN, -- USB Enable Power Output
-- Clocks.
Z80_CLK => Z80_CLK, -- Host CPU Clock
CLK_50M => CLK_50M -- 50MHz oscillator.
);
end architecture;

View File

@@ -0,0 +1,221 @@
---------------------------------------------------------------------------------------------------------
--
-- Name: tzpuFusionX_pkg.vhd
-- Created: June 2020
-- Author(s): Philip Smart
-- Description: tzpuFusionX CPLD configuration file.
--
-- This module contains parameters for the CPLD in the tzpuFusionX project
-- which targets the MZ-2000 host.
--
-- Credits:
-- Copyright: (c) 2018-22 Philip Smart <philip.smart@net2net.org>
--
-- History: June 2020 - Snapshot taken from the MZ2000 version of the tranZPUter SW-700 source.
--
---------------------------------------------------------------------------------------------------------
-- 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->.
---------------------------------------------------------------------------------------------------------
library ieee;
library pkgs;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
package tzpuFusionX_pkg is
------------------------------------------------------------
-- Constants
------------------------------------------------------------
-- Potential logic state constants.
constant YES : std_logic := '1';
constant NO : std_logic := '0';
constant HI : std_logic := '1';
constant LO : std_logic := '0';
constant ONE : std_logic := '1';
constant ZERO : std_logic := '0';
constant HIZ : std_logic := 'Z';
-- CPLD Command instructions.
constant CPLD_CMD_RESET_HOST : integer := 1;
constant CPLD_CMD_HOLD_HOST_BUS : integer := 2;
constant CPLD_CMD_RELEASE_HOST_BUS: integer := 3;
-- Target hardware modes.
constant MODE_MZ80K : integer := 0;
constant MODE_MZ80C : integer := 1;
constant MODE_MZ1200 : integer := 2;
constant MODE_MZ80A : integer := 3;
constant MODE_MZ700 : integer := 4;
constant MODE_MZ800 : integer := 5;
constant MODE_MZ80B : integer := 6;
constant MODE_MZ2000 : integer := 7;
-- Memory management modes.
constant TZMM_ORIG : integer := 00; -- Original Sharp mode, no tranZPUter features are selected except the I/O control registers (default: 0x60-063).
constant TZMM_BOOT : integer := 01; -- Original mode but E800-EFFF is mapped to tranZPUter RAM so TZFS can be booted.
constant TZMM_TZFS : integer := 02; -- TZFS main memory configuration. all memory is in tranZPUter RAM, E800-FFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected.
constant TZMM_TZFS2 : integer := 03; -- TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 1.
constant TZMM_TZFS3 : integer := 04; -- TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 2.
constant TZMM_TZFS4 : integer := 05; -- TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 3.
constant TZMM_CPM : integer := 06; -- CPM main memory configuration, all memory on the tranZPUter board, 64K block 4 selected. Special case for F3C0:F3FF & F7C0:F7FF (floppy disk paging vectors) which resides on the mainboard.
constant TZMM_CPM2 : integer := 07; -- CPM main memory configuration, F000-FFFF are on the tranZPUter board in block 4, 0040-CFFF and E800-EFFF are in block 5, mainboard for D000-DFFF (video), E000-E800 (Memory control) selected.
-- Special case for 0000:003F (interrupt vectors) which resides in block 4, F3FE:F3FF & F7FE:F7FF (floppy disk paging vectors) which resides on the mainboard.
constant TZMM_COMPAT : integer := 08; -- Compatibility monitor mode, monitor ROM on mainboard, RAM on tranZPUter in Block 0 1000-CFFF.
constant TZMM_HOSTACCESS : integer := 09; -- Monitor ROM 0000-0FFF and Main DRAM 0x1000-0xD000, video and memory mapped I/O are on the host machine, User/Floppy ROM E800-FFFF are in tranZPUter memory.
constant TZMM_MZ700_0 : integer := 10; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the mainboard.
constant TZMM_MZ700_1 : integer := 11; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
constant TZMM_MZ700_2 : integer := 12; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
constant TZMM_MZ700_3 : integer := 13; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
constant TZMM_MZ700_4 : integer := 14; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
constant TZMM_MZ800 : integer := 15; -- MZ800 Mode - Running on MZ800 hardware, configuration set according to MZ700/MZ800 mode.
constant TZMM_MZ2000 : integer := 16; -- MZ2000 Mode - Running on MZ2000 hardware, configuration set according to runtime configuration registers.
constant TZMM_FPGA : integer := 21; -- Open up access for the K64F to the FPGA resources such as memory. All other access to RAM or mainboard is blocked.
constant TZMM_TZPUM : integer := 22; -- Everything in on mainboard, no access to tranZPUter memory.
constant TZMM_TZPU : integer := 23; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
constant TZMM_TZPU0 : integer := 24; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
constant TZMM_TZPU1 : integer := 25; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 1 is selected.
constant TZMM_TZPU2 : integer := 26; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 2 is selected.
constant TZMM_TZPU3 : integer := 27; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 3 is selected.
constant TZMM_TZPU4 : integer := 28; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 4 is selected.
constant TZMM_TZPU5 : integer := 29; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 5 is selected.
constant TZMM_TZPU6 : integer := 30; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 6 is selected.
constant TZMM_TZPU7 : integer := 31; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 7 is selected.
------------------------------------------------------------
-- Configurable parameters.
------------------------------------------------------------
-- Target hardware.
constant CPLD_HOST_HW : integer := MODE_MZ700;
-- Target video hardware.
constant CPLD_HAS_FPGA_VIDEO : std_logic := '1';
-- Version of hdl.
constant CPLD_VERSION : integer := 2;
-- Clock source for the secondary clock. If a K64F is installed then enable it otherwise use the onboard oscillator.
--
constant USE_K64F_CTL_CLOCK : integer := 1;
------------------------------------------------------------
-- Function prototypes
------------------------------------------------------------
-- Find the maximum of two integers.
function IntMax(a : in integer; b : in integer) return integer;
-- Find the number of bits required to represent an integer.
function log2ceil(arg : positive) return natural;
-- Function to calculate the number of whole 'clock' cycles in a given time period, the period being in ns.
function clockTicks(period : in integer; clock : in integer) return integer;
-- Function to reverse the order of the bits in a standard logic vector.
-- ie. 1010 becomes 0101
function reverse_vector(slv:std_logic_vector) return std_logic_vector;
-- Function to convert an integer (0 or 1) into std_logic.
--
function to_std_logic(i : in integer) return std_logic;
-- Function to return the value of a bit as an integer for array indexing etc.
function bit_to_integer( s : std_logic ) return natural;
------------------------------------------------------------
-- Records
------------------------------------------------------------
------------------------------------------------------------
-- Components
------------------------------------------------------------
end tzpuFusionX_pkg;
------------------------------------------------------------
-- Function definitions.
------------------------------------------------------------
package body tzpuFusionX_pkg is
-- Find the maximum of two integers.
function IntMax(a : in integer; b : in integer) return integer is
begin
if a > b then
return a;
else
return b;
end if;
return a;
end function IntMax;
-- Find the number of bits required to represent an integer.
function log2ceil(arg : positive) return natural is
variable tmp : positive := 1;
variable log : natural := 0;
begin
if arg = 1 then
return 0;
end if;
while arg > tmp loop
tmp := tmp * 2;
log := log + 1;
end loop;
return log;
end function;
-- Function to calculate the number of whole 'clock' cycles in a given time period, the period being in ns.
function clockTicks(period : in integer; clock : in integer) return integer is
variable ticks : real;
variable fracTicks : real;
begin
ticks := (Real(period) * Real(clock)) / 1000000000.0;
fracTicks := ticks - CEIL(ticks);
if fracTicks > 0.0001 then
return Integer(CEIL(ticks + 1.0));
else
return Integer(CEIL(ticks));
end if;
end function;
function reverse_vector(slv:std_logic_vector) return std_logic_vector is
variable target : std_logic_vector(slv'high downto slv'low);
begin
for idx in slv'high downto slv'low loop
target(idx) := slv(slv'low + (slv'high-idx));
end loop;
return target;
end reverse_vector;
function to_std_logic(i : in integer) return std_logic is
begin
if i = 0 then
return '0';
end if;
return '1';
end function;
-- Function to return the value of a bit as an integer for array indexing etc.
function bit_to_integer( s : std_logic ) return natural is
begin
if s = '1' then
return 1;
else
return 0;
end if;
end function;
end package body;

View File

@@ -0,0 +1,30 @@
# -------------------------------------------------------------------------- #
#
# 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.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition
# Date created = 14:14:16 November 28, 2022
#
# -------------------------------------------------------------------------- #
QUARTUS_VERSION = "13.0"
DATE = "14:14:16 November 28, 2022"
# Revisions
PROJECT_REVISION = "tzpuFusionX_MZ700"

View File

@@ -0,0 +1,243 @@
# -------------------------------------------------------------------------- #
#
# 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.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition
# Date created = 16:29:32 June 24, 2020
#
# -------------------------------------------------------------------------- #
#
# Notes:
#
# 1) The default values for assignments are stored in the file:
# tzpuFusionX_MZ700.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.
#
# -------------------------------------------------------------------------- #
set_global_assignment -name FAMILY MAX7000AE
set_global_assignment -name DEVICE "EPM7512AETC144-10"
set_global_assignment -name TOP_LEVEL_ENTITY tzpuFusionX_MZ700
set_global_assignment -name ORIGINAL_QUARTUS_VERSION "13.0 SP1"
set_global_assignment -name PROJECT_CREATION_TIME_DATE "16:29:32 JUNE 24, 2020"
set_global_assignment -name LAST_QUARTUS_VERSION "13.0 SP1"
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR "-1"
set_global_assignment -name EDA_DESIGN_ENTRY_SYNTHESIS_TOOL "<None>"
set_global_assignment -name EDA_INPUT_VCC_NAME VCC -section_id eda_design_synthesis
set_global_assignment -name EDA_INPUT_DATA_FORMAT EDIF -section_id eda_design_synthesis
set_global_assignment -name EDA_SIMULATION_TOOL "ModelSim-Altera (VHDL)"
set_global_assignment -name EDA_OUTPUT_DATA_FORMAT VHDL -section_id eda_simulation
set_global_assignment -name OPTIMIZE_HOLD_TIMING OFF
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING OFF
set_global_assignment -name FITTER_EFFORT "STANDARD FIT"
set_global_assignment -name MAX7000_DEVICE_IO_STANDARD LVTTL
# Z80 Data Bus
# ============
set_location_assignment PIN_88 -to Z80_DATA[0]
set_location_assignment PIN_91 -to Z80_DATA[1]
set_location_assignment PIN_83 -to Z80_DATA[2]
set_location_assignment PIN_79 -to Z80_DATA[3]
set_location_assignment PIN_60 -to Z80_DATA[4]
set_location_assignment PIN_93 -to Z80_DATA[5]
set_location_assignment PIN_80 -to Z80_DATA[6]
set_location_assignment PIN_86 -to Z80_DATA[7]
# Z80 Control signals.
# ====================
set_location_assignment PIN_92 -to Z80_INTn
set_location_assignment PIN_96 -to Z80_NMIn
set_location_assignment PIN_97 -to Z80_HALTn
set_location_assignment PIN_98 -to Z80_MREQn
set_location_assignment PIN_99 -to Z80_IORQn
set_location_assignment PIN_110 -to Z80_RDn
set_location_assignment PIN_108 -to Z80_WRn
set_location_assignment PIN_107 -to Z80_BUSAKn
set_location_assignment PIN_106 -to Z80_WAITn
set_location_assignment PIN_103 -to Z80_BUSRQn
set_location_assignment PIN_100 -to Z80_RFSHn
set_location_assignment PIN_102 -to Z80_M1n
set_location_assignment PIN_56 -to Z80_RESETn
set_location_assignment PIN_101 -to Z80_CLK
# Z80 Address Bus
# ===============
set_location_assignment PIN_94 -to Z80_ADDR[0]
set_location_assignment PIN_90 -to Z80_ADDR[1]
set_location_assignment PIN_87 -to Z80_ADDR[2]
set_location_assignment PIN_84 -to Z80_ADDR[3]
set_location_assignment PIN_81 -to Z80_ADDR[4]
set_location_assignment PIN_78 -to Z80_ADDR[5]
set_location_assignment PIN_69 -to Z80_ADDR[6]
set_location_assignment PIN_70 -to Z80_ADDR[7]
set_location_assignment PIN_71 -to Z80_ADDR[8]
set_location_assignment PIN_68 -to Z80_ADDR[9]
set_location_assignment PIN_65 -to Z80_ADDR[10]
set_location_assignment PIN_67 -to Z80_ADDR[11]
set_location_assignment PIN_66 -to Z80_ADDR[12]
set_location_assignment PIN_63 -to Z80_ADDR[13]
set_location_assignment PIN_62 -to Z80_ADDR[14]
set_location_assignment PIN_61 -to Z80_ADDR[15]
# SOM SPI
# =======
set_location_assignment PIN_32 -to VSOM_SPI_CSn
set_location_assignment PIN_31 -to VSOM_SPI_CLK
set_location_assignment PIN_30 -to VSOM_SPI_MOSI
set_location_assignment PIN_29 -to VSOM_SPI_MISO
# SOM Parallel Bus
# ================
set_location_assignment PIN_41 -to VSOM_DATA_OUT[0]
set_location_assignment PIN_40 -to VSOM_DATA_OUT[1]
set_location_assignment PIN_39 -to VSOM_DATA_OUT[2]
set_location_assignment PIN_38 -to VSOM_DATA_OUT[3]
set_location_assignment PIN_37 -to VSOM_DATA_OUT[4]
set_location_assignment PIN_36 -to VSOM_DATA_OUT[5]
set_location_assignment PIN_35 -to VSOM_DATA_OUT[6]
set_location_assignment PIN_34 -to VSOM_DATA_OUT[7]
set_location_assignment PIN_132 -to VSOM_HBYTE
# SOM Reserved signals.
# =====================
set_location_assignment PIN_21 -to VSOM_RSV[1]
# SOM Control Signals
# ===================
set_location_assignment PIN_28 -to VSOM_READY
set_location_assignment PIN_18 -to VSOM_LTSTATE
set_location_assignment PIN_27 -to VSOM_BUSRQ
set_location_assignment PIN_26 -to VSOM_BUSACK
set_location_assignment PIN_19 -to VSOM_INT
set_location_assignment PIN_22 -to VSOM_NMI
set_location_assignment PIN_25 -to VSOM_WAIT
set_location_assignment PIN_23 -to VSOM_RESET
set_location_assignment PIN_16 -to PM_RESET
# VGA_Palette Control
# ===================
set_location_assignment PIN_133 -to VGA_R[7]
set_location_assignment PIN_137 -to VGA_R[8]
set_location_assignment PIN_140 -to VGA_R[9]
set_location_assignment PIN_134 -to VGA_G[7]
set_location_assignment PIN_138 -to VGA_G[8]
set_location_assignment PIN_141 -to VGA_G[9]
set_location_assignment PIN_136 -to VGA_B[8]
set_location_assignment PIN_139 -to VGA_B[9]
# VGA Control Signals
# ===================
set_location_assignment PIN_142 -to VGA_PXL_CLK
set_location_assignment PIN_14 -to VGA_DISPEN
set_location_assignment PIN_12 -to VGA_VSYNCn
set_location_assignment PIN_11 -to VGA_HSYNCn
set_location_assignment PIN_82 -to VGA_COLR
set_location_assignment PIN_109 -to VGA_CSYNCn
set_location_assignment PIN_143 -to VGA_BLANKn
# CRT Control Signals
# ===================
set_location_assignment PIN_15 -to MONO_PXL_CLK
set_location_assignment PIN_114 -to MONO_BLANKn
set_location_assignment PIN_113 -to MONO_CSYNCn
set_location_assignment PIN_116 -to MONO_RSV
# CRT Lower Chrominance Control
# =============================
set_location_assignment PIN_1 -to MONO_R[0]
set_location_assignment PIN_6 -to MONO_R[1]
set_location_assignment PIN_10 -to MONO_R[2]
set_location_assignment PIN_2 -to MONO_G[0]
set_location_assignment PIN_7 -to MONO_G[1]
set_location_assignment PIN_9 -to MONO_G[2]
set_location_assignment PIN_5 -to MONO_B[1]
set_location_assignment PIN_8 -to MONO_B[2]
# MUX Control Signals
# ===================
set_location_assignment PIN_72 -to VIDEO_SRC
set_location_assignment PIN_74 -to MONO_VIDEO_SRC
set_location_assignment PIN_77 -to AUDIO_SRC_L
set_location_assignment PIN_75 -to AUDIO_SRC_R
# Mainboard Reset Signals
# =======================
#set_location_assignment PIN_127 -to CPU_RESETn
set_location_assignment PIN_122 -to MB_RESETn
set_location_assignment PIN_111 -to MB_IPLn
# USB Power Control
# =================
set_location_assignment PIN_55 -to VBUS_EN
# Clocks
# ======
#set_location_assignment PIN_125 -to CPU_CLK
set_location_assignment PIN_128 -to CLK_50M
# Unused ports
# ============
#set_location_assignment PIN_42 -to
#set_location_assignment PIN_43 -to
#set_location_assignment PIN_44 -to
#set_location_assignment PIN_45 -to
#set_location_assignment PIN_112 -to
#set_location_assignment PIN_131 -to
#set_location_assignment PIN_117 -to
#set_location_assignment PIN_118 -to
#set_location_assignment PIN_119 -to
#set_location_assignment PIN_120 -to
#set_location_assignment PIN_121 -to
#set_location_assignment PIN_25 -to
#set_location_assignment PIN_53 -to
#set_location_assignment PIN_128 -to
#set_location_assignment PIN_47 -to
#set_location_assignment PIN_54 -to
#set_location_assignment PIN_127 -to
#set_location_assignment PIN_125 -to
#set_location_assignment PIN_48 -to
#set_location_assignment PIN_46 -to
#set_location_assignment PIN_49 -to
set_global_assignment -name VHDL_FILE ../tzpuFusionX_Toplevel.vhd
set_global_assignment -name VHDL_FILE ../tzpuFusionX_pkg.vhd
set_global_assignment -name VHDL_FILE ../tzpuFusionX.vhd
set_global_assignment -name SDC_FILE tzpuFusionX_MZ700_constraints.sdc
set_global_assignment -name VHDL_INPUT_VERSION VHDL_2008
set_global_assignment -name VHDL_SHOW_LMF_MAPPING_MESSAGES OFF
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS OFF
set_global_assignment -name MAX7000_OPTIMIZATION_TECHNIQUE AREA
set_global_assignment -name AUTO_RESOURCE_SHARING OFF
set_global_assignment -name PRE_MAPPING_RESYNTHESIS OFF
set_global_assignment -name USE_LOGICLOCK_CONSTRAINTS_IN_BALANCING OFF
set_global_assignment -name INFER_RAMS_FROM_RAW_LOGIC OFF
set_global_assignment -name AUTO_LCELL_INSERTION ON
set_global_assignment -name CDF_FILE output_files/tzpuFusionX_MZ700.cdf

View File

@@ -0,0 +1,324 @@
## Generated SDC file "tzpuFusionX.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.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition"
## DATE "Fri Jun 26 22:10:05 2020"
##
## DEVICE "EPM7160STC100-10"
##
#**************************************************************
# Time Information
#**************************************************************
set_time_format -unit ns -decimal_places 3
#**************************************************************
# Create Clock
#**************************************************************
# Standard mainboard clock. If using tzpuFusionX on a different host then set to the host frequency.
create_clock -name {Z80_CLK} -period 282.486 -waveform { 0.000 141.243 } [get_ports { Z80_CLK }]
# For 50MHz crystal.
create_clock -name {CLK_50M} -period 20.000 -waveform { 0.000 10.000 } [ get_ports { CLK_50M }]
# For SPI CSn
#create_clock -name {VSOM_SPI_CSn} -period 200.000 -waveform { 160.000 40.000 } [ get_ports { VSOM_SPI_CSn }]
# For SPI CLK
create_clock -name {VSOM_SPI_CLK} -period 14.000 -waveform { 0.000 7.000 } [ get_ports { VSOM_SPI_CLK }]
# For basic board with oscillator.
#create_clock -name {CTLCLK} -period 20.000 -waveform { 0.000 10.000 } [ get_ports { CTLCLK }]
#create_clock -name {cpld512:cpldl512Toplevel|CTLCLKi} -period 280.000 -waveform { 0.000 140.000 } [ get_keepers {cpld512:cpldl512Toplevel|CTLCLKi} ]
##create_clock -name {Z80_CLK} -period 50.000 -waveform { 0.000 25.000 } [get_ports { CTLCLK }]
#**************************************************************
# Create Generated Clock
#**************************************************************
#**************************************************************
# Set Clock Latency
#**************************************************************
#**************************************************************
# Set Clock Uncertainty
#**************************************************************
derive_clock_uncertainty
#**************************************************************
# Set Input Delay
#**************************************************************
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CTL_MBSEL}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CTL_BUSRQn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CTL_WAITn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {SYS_BUSRQn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {SYS_WAITn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_ADDR[*]}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_HI_ADDR[*]}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {VZ80_ADDR[*]}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_BUSACKn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_DATA[*]}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_HALTn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_IORQn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_M1n}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_MREQn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_RESETn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_RFSHn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_WRn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_RDn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {R_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {G_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {B_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {COLR_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CSYNC_IN}]
##set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CVIDEO_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {HSYNC_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {VSYNC_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {VZ80_DATA[*]}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_MREQn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_IORQn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_WRn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_RDn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_M1n}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_BUSACKn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_INTn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_NMIn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_WAITn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VWAITn_A21_V_CSYNC}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A20_RFSHn_V_HSYNC}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A19_HALTn_V_VSYNC}]
#**************************************************************
# Set Output Delay
#**************************************************************
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {CTL_BUSACKn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {CTL_HALTn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {CTL_M1n}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {CTL_RFSHn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {RAM_CSn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {RAM_CS2n}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {RAM_OEn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {RAM_WEn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {SVCREQn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {SYS_BUSACKn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_BUSRQn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_DATA[*]}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_ADDR[*]}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_HI_ADDR[*]}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_RA_ADDR[*]}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_WAITn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_MREQn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_CLK}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_ADDR[*]}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_DATA[*]}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_CLK}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_MREQn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_IORQn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_RDn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_WRn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_M1n}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VIDEO_RDn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VIDEO_WRn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A18_INTn_V_R}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_BUSRQn_V_G}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A16_WAITn_V_B}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A17_NMIn_V_COLR}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VWAITn_A21_V_CSYNC}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A20_RFSHn_V_HSYNC}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A19_HALTn_V_VSYNC}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_HALTn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_RFSHn}]
# For K64F
#set_output_delay -add_delay -clock [get_clocks {CTLCLK}] 5.000 [get_ports {Z80_CLK}]
# For basic board with oscillator.
#set_output_delay -add_delay -clock [get_clocks {cpld512:cpldl512Toplevel|CTLCLKi}] 5.000 [get_ports {Z80_CLK}]
#**************************************************************
# Set Max Delay
#**************************************************************
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_HALTn} 30.000
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_IORQn} 30.000
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_M1n} 30.000
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_RDn} 30.000
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_WRn} 30.000
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_RFSHn} 30.000
#set_max_delay -from [get_ports {VZ80_A19_HALTn_V_VSYNC}] -to {Z80_HALTn} 30.000
#set_max_delay -from [get_ports {VZ80_IORQn}] -to {Z80_IORQn} 30.000
#set_max_delay -from [get_ports {VZ80_MREQn}] -to {Z80_IORQn} 30.000
#set_max_delay -from [get_ports {VZ80_M1n}] -to {Z80_M1n} 30.000
#set_max_delay -from [get_ports {VZ80_RDn}] -to {Z80_RDn} 30.000
#set_max_delay -from [get_ports {VZ80_WRn}] -to {Z80_WRn} 30.000
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_HALTn} 40.000
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_RFSHn} 40.000
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_IORQn} 40.000
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_M1n} 30.000
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_RDn} 30.000
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_WRn} 30.000
#set_max_delay -from [get_ports {VZ80_A20_RFSHn_V_HSYNC}] -to {Z80_RFSHn} 30.000
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_HALTn} 30.000
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_IORQn} 30.000
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_M1n} 30.000
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_RDn} 30.000
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_WRn} 30.000
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_RFSHn} 30.000
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_HALTn}] 45.000
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_IORQn}] 30.000
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_M1n}] 30.000
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_RDn}] 30.000
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_RFSHn}] 45.000
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_WRn}] 30.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_HALTn}] 45.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_IORQn}] 50.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_M1n}] 40.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_RDn}] 40.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_WRn}] 40.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_RFSHn}] 45.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_HALTn}] 60.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_IORQn}] 45.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_M1n}] 40.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_RDn}] 40.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_WRn}] 40.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_RFSHn}] 60.000
#**************************************************************
# Set Min Delay
#**************************************************************
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_HALTn} 1.000
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_IORQn} 1.000
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_M1n} 1.000
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_RDn} 1.000
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_WRn} 1.000
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_RFSHn} 1.000
#set_min_delay -from [get_ports {VZ80_A19_HALTn_V_VSYNC}] -to {Z80_HALTn} 1.000
#set_min_delay -from [get_ports {VZ80_IORQn}] -to {Z80_IORQn} 1.000
#set_min_delay -from [get_ports {VZ80_MREQn}] -to {Z80_IORQn} 1.000
#set_min_delay -from [get_ports {VZ80_M1n}] -to {Z80_M1n} 1.000
#set_min_delay -from [get_ports {VZ80_RDn}] -to {Z80_RDn} 1.000
#set_min_delay -from [get_ports {VZ80_WRn}] -to {Z80_WRn} 1.000
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_HALTn} 1.000
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_RFSHn} 1.000
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_IORQn} 1.000
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_M1n} 1.000
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_RDn} 1.000
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_WRn} 1.000
#set_min_delay -from [get_ports {VZ80_A20_RFSHn_V_HSYNC}] -to {Z80_RFSHn} 1.000
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_HALTn} 1.000
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_IORQn} 1.000
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_M1n} 1.000
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_RDn} 1.000
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_WRn} 1.000
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_RFSHn} 1.000
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_HALTn}] 1.000
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_IORQn}] 1.000
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_M1n}] 1.000
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_RDn}] 1.000
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_RFSHn}] 1.000
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_WRn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_HALTn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_IORQn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_M1n}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_RDn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_WRn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_RFSHn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_HALTn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_IORQn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_M1n}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_RDn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_WRn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_RFSHn}] 1.000
#**************************************************************
# Set Clock Groups
#**************************************************************
#**************************************************************
# Set False Path
#**************************************************************
# For K64F
#set_false_path -from [get_clocks {CTLCLK}] -to [get_clocks {SYSCLK}]
#set_false_path -from [get_clocks {SYSCLK}] -to [get_clocks {CTLCLK}]
# For basic board with oscillator.
#set_false_path -from [get_clocks {cpld512:cpldl512Toplevel|CTLCLKi}] -to [get_clocks {SYSCLK}]
#set_false_path -from [get_clocks {cpld512:cpldl512Toplevel|CTLCLKi}] -to [get_clocks {CTLCLK}]
#set_false_path -from [get_clocks {SYSCLK}] -to [get_clocks {cpld512:cpldl512Toplevel|CTLCLKi}]
#set_false_path -from [get_clocks {SYSCLK}] -to [get_clocks {CTLCLK}]
# For both configurations.
#set_false_path -from {cpld512:cpldl512Toplevel|KEY_SUBSTITUTE} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|MZ80B_VRAM_HI_ADDR} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|MZ80B_VRAM_LO_ADDR} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|MODE_VIDEO_MZ80B} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|GRAM_PAGE_ENABLE} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#**************************************************************
# Set Multicycle Path
#**************************************************************
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CTL_BUSRQni} -to {cpld512:cpldl512Toplevel|CTLCLK_Q} -setup -end 2
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CTL_BUSRQni} -to {cpld512:cpldl512Toplevel|CTLCLK_Q} -hold -end 1
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CTL_BUSRQni} -to {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -setup -end 2
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CTL_BUSRQni} -to {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -hold -end 1
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -setup -end 2
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -hold -end 1
#**************************************************************
# Set Maximum Delay
#**************************************************************
#**************************************************************
# Set Minimum Delay
#**************************************************************
#**************************************************************
# Set Input Transition
#**************************************************************

View File

@@ -0,0 +1,999 @@
-------------------------------------------------------------------------------------------------------
--
-- Name: tzpuFusionX.vhd
-- Version: MZ-700
-- Created: June 2020
-- Author(s): Philip Smart
-- Description: tzpuFusionX CPLD logic definition file.
-- This module contains the definition of the tzpuFusionX project plus enhancements
-- for the MZ700.
--
-- Credits:
-- Copyright: (c) 2018-22 Philip Smart <philip.smart@net2net.org>
--
-- History: Oct 2022 - Initial write for the MZ-700.
--
---------------------------------------------------------------------------------------------------------
-- 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->.
---------------------------------------------------------------------------------------------------------
library ieee;
library pkgs;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use work.tzpuFusionX_pkg.all;
entity cpld512 is
generic (
SPI_CLK_POLARITY : std_logic := '0'
);
port (
-- Z80 Address Bus
Z80_ADDR : inout std_logic_vector(15 downto 0);
-- Z80 Data Bus
Z80_DATA : inout std_logic_vector(7 downto 0);
-- Z80 Control signals.
Z80_BUSRQn : in std_logic;
Z80_BUSAKn : out std_logic;
Z80_INTn : in std_logic;
Z80_IORQn : inout std_logic;
Z80_MREQn : inout std_logic;
Z80_NMIn : in std_logic;
Z80_RDn : inout std_logic;
Z80_WRn : inout std_logic;
Z80_RESETn : in std_logic; -- Host CPU Reset signal, also CPLD reset.
Z80_HALTn : out std_logic;
Z80_WAITn : in std_logic;
Z80_M1n : inout std_logic;
Z80_RFSHn : inout std_logic;
-- SOM Control Signals
VSOM_SPI_CLK : in std_logic; -- SOM SPI Channel 0 Clock.
VSOM_SPI_MOSI : in std_logic; -- MOSI Input.
VSOM_SPI_MISO : out std_logic; -- MISO Output.
VSOM_SPI_CSn : in std_logic; -- Enable.
-- SOM Parallel Bus.
VSOM_DATA_OUT : out std_logic_vector(7 downto 0); -- Address/Data bus for CPLD control registers.
VSOM_HBYTE : in std_logic; -- Parallel Bus High (1)/Low (0) byte.
VSOM_READY : out std_logic; -- FSM Ready (1), Busy (0)
VSOM_LTSTATE : out std_logic; -- Last T-State in current cycle, 1 = active.
VSOM_BUSRQ : out std_logic; -- Host device requesting Z80 Bus.
VSOM_BUSACK : out std_logic; -- Host device granted Z80 Bus
VSOM_INT : out std_logic; -- Z80 INT signal
VSOM_NMI : out std_logic; -- Z80 NMI signal
VSOM_WAIT : out std_logic; -- Z80 WAIT signal
VSOM_RESET : out std_logic; -- Z80 RESET signal
VSOM_RSV : out std_logic_vector(1 downto 1); -- Reserved pins.
-- SOM Control Signals
PM_RESET : out std_logic; -- Reset SOM
-- VGA_Palette Control
VGA_R : in std_logic_vector(9 downto 7); -- Signals used for detecting blank or no video output.
VGA_G : in std_logic_vector(9 downto 7);
VGA_B : in std_logic_vector(9 downto 8);
-- VGA Control Signals
VGA_PXL_CLK : in std_logic; -- VGA Pixel clock for DAC conversion.
VGA_DISPEN : in std_logic; -- Displayed Enabled (SOM video output).
VGA_VSYNCn : in std_logic; -- SOM VSync.
VGA_HSYNCn : in std_logic; -- SOM HSync.
VGA_COLR : out std_logic; -- COLR colour carrier frequency.
VGA_CSYNCn : out std_logic; -- VGA Composite Sync.
VGA_BLANKn : out std_logic; -- VGA Blank detected.
-- CRT Control Signals
MONO_PXL_CLK : out std_logic; -- Mono CRT pixel clock for DAC conversion.
MONO_BLANKn : out std_logic; -- Mono CRT Blank (no active pixel) detection.
MONO_CSYNCn : out std_logic; -- Mono CRT composite sync.
MONO_RSV : out std_logic;
-- CRT Lower Chrominance Control
MONO_R : out std_logic_vector(2 downto 0); -- Signals to fine tune Red level of monochrome chrominance.
MONO_G : out std_logic_vector(2 downto 0); -- Signals to fine tune Green level of monochrome chrominance.
MONO_B : out std_logic_vector(2 downto 1); -- Signals to fine tune Blue level of monochrome chrominance.
-- MUX Control Signals
VIDEO_SRC : out std_logic; -- Select video source, Mainboard or SOM.
MONO_VIDEO_SRC : out std_logic; -- Select crt video source, Mainboard or SOM.
AUDIO_SRC_L : out std_logic; -- Select Audio Source Left Channel, Mainboard or SOM.
AUDIO_SRC_R : out std_logic; -- Select Audio Source Right Channel, Mainboard or SOM.
-- Mainboard Reset Signals
MB_RESETn : in std_logic; -- Motherboard Reset pressed.
MB_IPLn : in std_logic; -- Motherboard IPL pressed.
-- USB Power Control
VBUS_EN : out std_logic; -- USB Enable Power Output
-- Clocks.
Z80_CLK : in std_logic; -- Host CPU Clock
CLK_50M : in std_logic -- 50MHz oscillator.
);
end entity;
architecture rtl of cpld512 is
-- Finite State Machine states.
type SOMFSMState is
(
IdleCycle,
FetchCycle,
FetchCycle_2,
FetchCycle_3,
FetchCycle_4,
RefreshCycle,
RefreshCycle_1,
RefreshCycle_2,
RefreshCycle_3,
WriteCycle,
WriteCycle_2,
WriteCycle_3,
WriteCycle_4,
ReadCycle,
ReadCycle_2,
ReadCycle_3,
ReadCycle_4,
WriteIOCycle,
WriteIOCycle_2,
WriteIOCycle_3,
WriteIOCycle_4,
WriteIOCycle_5,
ReadIOCycle,
ReadIOCycle_2,
ReadIOCycle_3,
ReadIOCycle_4,
HaltCycle,
BusReqCycle
);
-- CPU Interface internal signals.
signal Z80_BUSRQni : std_logic;
signal Z80_BUSAKni : std_logic;
signal Z80_INTni : std_logic;
signal Z80_IORQni : std_logic;
signal Z80_MREQni : std_logic;
signal Z80_NMIni : std_logic;
signal Z80_RDni : std_logic;
signal Z80_WRni : std_logic;
signal Z80_HALTni : std_logic;
signal Z80_WAITni : std_logic;
signal Z80_M1ni : std_logic;
signal Z80_RFSHni : std_logic;
signal Z80_DATAi : std_logic_vector(7 downto 0);
signal Z80_BUSRQ_ACKni : std_logic;
-- Internal CPU state control.
signal CPU_ADDR : std_logic_vector(15 downto 0) := (others => '0');
signal CPU_DATA_IN : std_logic_vector(7 downto 0) := (others => '0');
signal CPU_DATA_OUT : std_logic_vector(7 downto 0) := (others => '0');
signal CPU_DATA_EN : std_logic;
-- Clocks.
signal CLK_25Mi : std_logic := '0';
-- Reset control
signal PM_RESETi : std_logic := '1';
signal VSOM_RESETni : std_logic := '1';
-- Refresh control.
signal FSM_STATE : SOMFSMState := IdleCycle;
signal NEW_SPI_CMD : std_logic := '0';
signal VCPU_CS_EDGE : std_logic_vector(1 downto 0) := "11";
signal AUTOREFRESH_CNT : integer range 0 to 7;
signal FSM_STATUS : std_logic := '0';
signal RFSH_STATUS : std_logic := '0';
signal REFRESH_ADDR : std_logic_vector(7 downto 0);
signal IPAR : std_logic_vector(7 downto 0);
signal AUTOREFRESH : std_logic;
-- Clock edge detection and flagging.
signal Z80_CLK_RE : std_logic := '0';
signal Z80_CLK_FE : std_logic := '0';
signal Z80_CLK_LEVEL : std_logic := '0';
signal Z80_CLK_LAST : std_logic := '0';
signal CPU_T_STATE : integer range 0 to 5;
signal CPU_T_STATES : integer range 0 to 5;
signal CPU_T_STATE_SET : integer range 0 to 5;
signal CPU_LAST_T_STATE : std_logic := '0';
-- SPI Slave interface.
signal SPI_SHIFT_EN : std_logic;
signal SPI_TX_SREG : std_logic_vector(6 downto 0); -- TX Shift Register
signal SPI_RX_SREG : std_logic_vector(7 downto 0); -- RX Shift Register
signal SPI_TX_DATA : std_logic_vector(31 downto 0); -- Data to transmit.
signal SPI_RX_DATA : std_logic_vector(31 downto 0); -- Data received.
signal SPI_BIT_CNT : integer range 0 to 16; -- Count of bits tx/rx'd.
signal SPI_FRAME_CNT : integer range 0 to 4; -- Number of frames received (8bit chunks).
-- SPI Command interface.
signal SOM_CMD : std_logic_vector(7 downto 0) := (others => '0');
signal SPI_NEW_DATA : std_logic;
signal SPI_PROCESSING : std_logic;
signal SPI_CPU_ADDR : std_logic_vector(15 downto 0) := (others => '0');
signal SPI_CPU_DATA : std_logic_vector(7 downto 0) := (others => '0');
-- Test modes.
signal SPI_LOOPBACK_TEST : std_logic := '0';
-- Video/Audio control
signal VIDEO_SRCi : std_logic := '0';
signal MONO_VIDEO_SRCi : std_logic := '0';
signal AUDIO_SRC_Li : std_logic := '0';
signal AUDIO_SRC_Ri : std_logic := '0';
signal VBUS_ENi : std_logic := '1';
function to_std_logic(L: boolean) return std_logic is
begin
if L then
return('1');
else
return('0');
end if;
end function to_std_logic;
begin
-- System RESET.
--
-- Multiple reset sources, Z80_RESETn, MB_IPLn, MB_RESETn. On the MZ-700 we are only concerned with the Z80_RESETn.
-- If the external reset switch is pressed, a Z80_RESETn is invoked sending the signal low for approx 30ms.
-- On the first edge the VSOM_RESETn signal is set which allows the SOM to see it and the Z80 application to enter a reset state.
-- On the second edge, if occurring within 1 second of the first, the PM_RESET signal to the SOM is triggered, held low for 1 second,
-- forcing the SOM to reboot.
SYSRESET: process( Z80_CLK, Z80_RESETn )
variable timer1 : integer range 0 to 354000 := 0;
variable timer100 : integer range 0 to 10 := 0;
variable timerPMReset : integer range 0 to 10 := 0;
variable resetCount : integer range 0 to 3 := 0;
variable cpuResetEdge : std_logic := '1';
begin
-- Synchronous on the HOST Clock.
if(rising_edge(Z80_CLK)) then
-- If the PM Reset timer is active, count down and on expiry release the SOM PM_RESET line.
if(timerPMReset = 0 and PM_RESETi = '1') then
PM_RESETi <= '0';
end if;
-- If the VSOM_RESETni is active after reset timer expiry, cancel the RESET state.
if(timerPMReset = 0 and VSOM_RESETni = '0') then
VSOM_RESETni <= '1';
end if;
-- Each time the reset button is pressed, count the edges.
if(Z80_RESETn = '0' and cpuResetEdge = '1' and (resetCount = 0 or timer100 > 5)) then
resetCount := resetCount + 1;
VSOM_RESETni <= '0';
timerPMReset := 5;
timer100 := 0;
-- If there are 2 or more reset signals in a given period it means a SOM reset is required.
if(resetCount >= 2) then
PM_RESETi <= '1';
timerPMReset := 10;
resetCount := 0;
end if;
end if;
-- 100ms interval.
if(timer1 = 354000) then
timer100 := timer100 + 1;
if(timer100 >= 10) then
timer100 := 0;
resetCount := 0;
end if;
if(timerPMReset > 0) then
timerPMReset := timerPMReset - 1;
end if;
end if;
timer1 := timer1 - 1;
cpuResetEdge := Z80_RESETn;
end if;
end process;
-- Create Mono DAC Clock based on primary clock.
MONOCLK: process( CLK_50M )
begin
if(rising_edge(CLK_50M)) then
CLK_25Mi <= not CLK_25Mi;
end if;
end process;
-- SPI Slave input. Receive command and data from the SOM.
SPI_INPUT : process(VSOM_SPI_CLK)
begin
-- SPI_CLK_POLARITY='0' => falling edge; SPI_CLK_POLARITY='1' => rising edge
if(VSOM_SPI_CLK'event and VSOM_SPI_CLK = SPI_CLK_POLARITY) then
if(VSOM_SPI_CSn = '0') then
SPI_RX_SREG <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
-- End of frame then store the data prior to next bit arrival.
-- Convert to Little Endian, same as SOM.
if(SPI_SHIFT_EN = '1' and SPI_FRAME_CNT = 1 and SPI_BIT_CNT = 0) then
SPI_RX_DATA(7 downto 0) <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
elsif(SPI_SHIFT_EN = '1' and SPI_FRAME_CNT = 2 and SPI_BIT_CNT = 0) then
SPI_RX_DATA(15 downto 8) <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
elsif(SPI_SHIFT_EN = '1' and SPI_FRAME_CNT = 3 and SPI_BIT_CNT = 0) then
SPI_RX_DATA(23 downto 16) <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
elsif(SPI_SHIFT_EN = '1' and SPI_FRAME_CNT = 4 and SPI_BIT_CNT = 0) then
SPI_RX_DATA(31 downto 24) <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
end if;
end if;
end if;
end process;
-- SPI Slave output. Return the current data set as selected by the input signals XACT.
SPI_OUTPUT : process(VSOM_SPI_CLK,VSOM_SPI_CSn,SPI_TX_DATA)
begin
if(VSOM_SPI_CSn = '1') then
SPI_SHIFT_EN <= '0';
SPI_BIT_CNT <= 15;
-- SPI_CLK_POLARITY='0' => falling edge; SPI_CLK_POLARITY='1' => risinge edge
elsif(VSOM_SPI_CLK'event and VSOM_SPI_CLK = not SPI_CLK_POLARITY) then
SPI_SHIFT_EN <= '1';
if(SPI_BIT_CNT > 0) then
SPI_BIT_CNT <= SPI_BIT_CNT - 1;
end if;
VSOM_SPI_MISO <= SPI_TX_SREG(6);
SPI_TX_SREG <= SPI_TX_SREG(5 downto 0) & '0';
-- First clock after CS goes active, load up the data to be sent to the SOM.
if(SPI_SHIFT_EN = '0' or SPI_BIT_CNT = 0) then
if(SPI_LOOPBACK_TEST = '1') then
VSOM_SPI_MISO<= SPI_RX_SREG(7);
SPI_TX_SREG <= SPI_RX_SREG(6 downto 0);
elsif(SPI_SHIFT_EN = '0') then
SPI_FRAME_CNT<= 1;
VSOM_SPI_MISO<= SPI_TX_DATA(7);
SPI_TX_SREG <= SPI_TX_DATA(6 downto 0);
elsif(SPI_FRAME_CNT = 1) then
SPI_FRAME_CNT<= 2;
VSOM_SPI_MISO<= SPI_TX_DATA(15);
SPI_TX_SREG <= SPI_TX_DATA(14 downto 8);
elsif(SPI_FRAME_CNT = 2) then
SPI_FRAME_CNT<= 3;
VSOM_SPI_MISO<= SPI_TX_DATA(23);
SPI_TX_SREG <= SPI_TX_DATA(22 downto 16);
else
-- Increment frame count for each word received. We handle 8bit (1 frame), 16bit (2 frames) or 32bit (4 frames) reception.
SPI_FRAME_CNT<= 4;
VSOM_SPI_MISO<= SPI_TX_DATA(31);
SPI_TX_SREG <= SPI_TX_DATA(30 downto 24);
end if;
SPI_BIT_CNT <= 7;
end if;
end if;
end process;
SPI_REGISTER : process(Z80_RESETn, VSOM_SPI_CSn, SPI_FRAME_CNT)
begin
if(Z80_RESETn = '0') then
VIDEO_SRCi <= '0';
VGA_BLANKn <= '1';
VBUS_ENi <= '1';
MONO_VIDEO_SRCi <= '1';
AUDIO_SRC_Li <= '0';
AUDIO_SRC_Ri <= '0';
AUTOREFRESH <= '1';
SPI_LOOPBACK_TEST <= '0';
SOM_CMD <= (others => '0');
SPI_CPU_ADDR <= (others => '0');
SPI_NEW_DATA <= '0';
-- On rising edge of SPI CSn a new data packet from the SOM has arrived and in the shift register SPI_RX_SREG.
-- The variable SPI_FRAME_CNT indicates which byte (frame) in a 32bit word has been transmitted. This allows
-- for 8bit, 16bit and 32bit transmissions.
-- The packet is formatted as follows:
--
-- < SPI_FRAME_CNT=4 >< SPI_FRAME=3 > < SPI_FRAME_CNT=2 >< SPI_FRAME_CNT=1>
-- < 16bit Z80 Address > < Z80 Data >< Command = 00.. 80 >
-- 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 2 0
--
-- < > < Data >< Command = F0.. FF >
-- 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 2 0
--
elsif(VSOM_SPI_CSn'event and VSOM_SPI_CSn = '1') then
-- Command is always located in the upper byte of frame 1.
SOM_CMD <= SPI_RX_DATA(7 downto 0);
-- Toggle flag to indicate new data arrived.
SPI_NEW_DATA <= not SPI_NEW_DATA;
-- Process the command. Some commands require the FSM, others can be serviced immediately.
case SPI_RX_DATA(7 downto 0) is
-- Z80XACT(0..15): Setup data and address as provided then execute FSM.
when X"10" | X"11" | X"12" | X"13" | X"14" | X"15" | X"16" | X"17" | -- Fetch
X"18" | X"19" | X"1A" | X"1B" | X"1C" | X"1D" | X"1E" | X"1F" | -- Write
X"20" | X"21" | X"22" | X"23" | X"24" | X"25" | X"26" | X"27" | -- Read
X"28" | X"29" | X"2A" | X"2B" | X"2C" | X"2D" | X"2E" | X"2F" | -- WriteIO
X"30" | X"31" | X"32" | X"33" | X"34" | X"35" | X"36" | X"37" | -- ReadIO
X"38" | X"39" | X"3A" | X"3B" | X"3C" | X"3D" | X"3E" | X"3F" | --
X"40" | X"41" | X"42" | X"43" | X"44" | X"45" | X"46" | X"47" | --
X"48" | X"49" | X"4A" | X"4B" | X"4C" | X"4D" | X"4E" | X"4F" =>
-- Direct address set.
if(SPI_FRAME_CNT = 4) then
SPI_CPU_ADDR <= SPI_RX_DATA(31 downto 16);
else
SPI_CPU_ADDR <= std_logic_vector(unsigned(CPU_ADDR) + unsigned(SPI_RX_DATA(2 downto 0)));
end if;
if(SPI_FRAME_CNT > 1) then
SPI_CPU_DATA <= SPI_RX_DATA(15 downto 8);
end if;
-- SETSIGSET1: Set control lines directly.
when X"F0" =>
VIDEO_SRCi <= SPI_RX_DATA(8);
MONO_VIDEO_SRCi <= SPI_RX_DATA(9);
AUDIO_SRC_Li <= SPI_RX_DATA(10);
AUDIO_SRC_Ri <= SPI_RX_DATA(11);
VBUS_ENi <= SPI_RX_DATA(12);
VGA_BLANKn <= not SPI_RX_DATA(13);
-- Enable auto refresh DRAM cycle.
when X"F1" =>
AUTOREFRESH <= '1';
-- Disable auto refresh DRAM cycle.
when X"F2" =>
AUTOREFRESH <= '0';
-- SETLOOPBACK: Enable loopback test mode.
when X"FE" =>
SPI_LOOPBACK_TEST <= '1';
-- No action, called to retrieve status.
when X"00" | X"FF" =>
when others =>
end case;
end if;
end process;
-- Z80 Clock edge detection. Each falling and rising edge sets a flag for 1 cycle along with the current clock level flag.
-- On expiry of the defined T-States, a flag is raised to indicate end of cycle.
CLKEDGE: process( CLK_50M, Z80_RESETn, Z80_CLK, CPU_T_STATE_SET )
begin
if(Z80_RESETn = '0') then
Z80_CLK_RE <= '0';
Z80_CLK_FE <= '0';
Z80_CLK_LEVEL <= '0';
CPU_T_STATE <= 1;
CPU_LAST_T_STATE <= '0';
elsif(rising_edge(CLK_50M)) then
-- Host clock edge detection. For Z80 operations the clock edge is required to meet host and original timings.
if(Z80_CLK = '1' and Z80_CLK_LAST = '0') then
Z80_CLK_RE <= '1';
Z80_CLK_LEVEL <= '1';
-- T state increments on each rising edge unless WAIT asserted.
if(Z80_WAITni = '1') then
-- Wrap around to next T-State if limit for last transaction type reached.
if(CPU_T_STATE = CPU_T_STATES) then
CPU_T_STATE <= 1;
CPU_LAST_T_STATE <= '0';
else
CPU_T_STATE <= CPU_T_STATE + 1;
end if;
end if;
elsif(Z80_CLK = '0' and Z80_CLK_LAST = '1') then
Z80_CLK_FE <= '1';
Z80_CLK_LEVEL <= '0';
-- Falling edge of the last T-State sets the Last T-State flag. This gives the SOM sufficient time to detect it
-- and execute necessary code before next T-State commences.
if(CPU_T_STATE = CPU_T_STATES) then
CPU_LAST_T_STATE <= '1';
end if;
else
Z80_CLK_RE <= '0';
Z80_CLK_FE <= '0';
end if;
-- Mechanism to set the T-State.
if(CPU_T_STATE_SET /= 0) then
CPU_T_STATE <= CPU_T_STATE_SET;
CPU_LAST_T_STATE <= '0';
end if;
Z80_CLK_LAST <= Z80_CLK;
end if;
end process;
-- SOM Finite State Machine.
--
-- A command processor, based on an FSM concept, to process requested commands, ie. Z80 Write, Z80 Read etc.
-- The external signal SOM_CMD_EN, when set, indicates a new command available in SOM_CMD.
--
SOMFSM: process( CLK_50M, Z80_RESETn )
begin
if(Z80_RESETn = '0') then
Z80_BUSAKni <= '1';
Z80_IORQni <= '1';
Z80_MREQni <= '1';
Z80_RDni <= '1';
Z80_WRni <= '1';
Z80_HALTni <= '1';
Z80_M1ni <= '1';
Z80_RFSHni <= '1';
Z80_BUSRQ_ACKni <= '1';
FSM_STATUS <= '0';
RFSH_STATUS <= '0';
CPU_DATA_EN <= '0';
CPU_DATA_IN <= (others => '0');
REFRESH_ADDR <= (others => '0');
AUTOREFRESH_CNT <= 7;
IPAR <= (others => '0');
FSM_STATE <= IdleCycle;
NEW_SPI_CMD <= '0';
VCPU_CS_EDGE <= "11";
CPU_T_STATES <= 3;
CPU_T_STATE_SET <= 0;
SPI_PROCESSING <= '0';
elsif(rising_edge(CLK_50M)) then
-- Setup of T State is one cycle wide.
CPU_T_STATE_SET <= 0;
-- Bus request mechanism. If an externel Bus Request comes in and the FSM is idle, run the Bus Request command which
-- suspends processing and tri-states the bus.
if(Z80_BUSRQn = '0' and Z80_BUSRQ_ACKni = '1' and FSM_STATE = IdleCycle) then
FSM_STATE <= BusReqCycle;
end if;
if(Z80_BUSRQn = '1' and Z80_BUSRQ_ACKni = '0' and FSM_STATE = IdleCycle) then
Z80_BUSRQ_ACKni <= '1';
end if;
-- New command, set flag as the signal is only 1 clock wide.
if(SPI_LOOPBACK_TEST = '0' and VSOM_SPI_CSn = '1' and VCPU_CS_EDGE = "01") then
NEW_SPI_CMD <= '1';
end if;
-- Whenever we return to Idle or just prior to Refresh from a Fetch cycle set all control signals to default.
if(FSM_STATE = IdleCycle or FSM_STATE = RefreshCycle) then
CPU_DATA_EN <= '0';
Z80_MREQni <= '1';
Z80_IORQni <= '1';
Z80_RDni <= '1';
Z80_WRni <= '1';
Z80_M1ni <= '1';
FSM_STATUS <= '0';
Z80_RFSHni <= '1';
-- Auto DRAM refresh cycles. When enabled, every 7 host clock cycles, a 2 cycle refresh period commences.
-- This will be overriden if the SPI receives a new command.
--
if AUTOREFRESH = '1' and FSM_STATE = IdleCycle then
AUTOREFRESH_CNT <= AUTOREFRESH_CNT - 1;
if(AUTOREFRESH_CNT = 0) then
FSM_STATE <= RefreshCycle_3;
end if;
end if;
end if;
-- If new command has been given and the FSM enters idle state, load up new command for processing.
if(NEW_SPI_CMD = '1' and FSM_STATE = IdleCycle) then
NEW_SPI_CMD <= '0';
-- Store new address and data for this command.
CPU_ADDR <= SPI_CPU_ADDR;
if(SPI_CPU_DATA /= CPU_DATA_OUT) then
CPU_DATA_OUT <= SPI_CPU_DATA;
end if;
-- Process the SOM command. The SPI_REGISTER executes non FSM commands and stores FSM
-- data prior to this execution block, which fires 1 cycle later on the same control clock.
-- If the command is not for the FSM then the READY mechanism is held for one
-- further cycle before going inactive.
case SOM_CMD is
when X"10" | X"11" | X"12" | X"13" | X"14" | X"15" | X"16" | X"17" =>
-- Initiate a Fetch Cycle.
FSM_STATE <= FetchCycle;
when X"18" | X"19" | X"1A" | X"1B" | X"1C" | X"1D" | X"1E" | X"1F" =>
-- Set the Z80 data bus value and initiate a Write Cycle.
FSM_STATE <= WriteCycle;
when X"20" | X"21" | X"22" | X"23" | X"24" | X"25" | X"26" | X"27" =>
-- Initiate a Read Cycle.
FSM_STATE <= ReadCycle;
when X"28" | X"29" | X"2A" | X"2B" | X"2C" | X"2D" | X"2E" | X"2F" =>
-- Set the Z80 data bus value and initiate an IO Write Cycle.
-- The SOM should set 15:8 to the B register value.
FSM_STATE <= WriteIOCycle;
when X"30" | X"31" | X"32" | X"33" | X"34" | X"35" | X"36" | X"37" =>
-- Initiate a Read IO Cycle.
FSM_STATE <= ReadIOCycle;
when X"50" =>
-- Register a Halt state.
FSM_STATE <= HaltCycle;
when X"51" =>
-- Initiate a refresh cycle.
FSM_STATE <= RefreshCycle_3;
when X"E0" =>
-- Initiate a Halt Cycle.
FSM_STATE <= HaltCycle;
-- Set the Refresh Address register.
when X"E1" =>
REFRESH_ADDR <= CPU_DATA_OUT;
-- Set the Interrupt Page Address Register.
when X"E2" =>
IPAR <= CPU_DATA_OUT;
when others =>
end case;
-- Toggle the processing flag to negate the new data flag. Used to indicate device is busy.
if(SPI_NEW_DATA /= SPI_PROCESSING) then
SPI_PROCESSING <= not SPI_PROCESSING;
end if;
-- FSM Status bit. When processing a command it is set, cleared when idle. Used by SOM to determine command completion.
FSM_STATUS <= '1';
end if;
-- Refresh status bit. Indicates a Refresh cycle is under way.
if FSM_STATE = RefreshCycle or FSM_STATE = RefreshCycle_1 or FSM_STATE = RefreshCycle_2 or FSM_STATE = RefreshCycle_3 then
RFSH_STATUS <= '1';
else
RFSH_STATUS <= '0';
end if;
-- FSM to implement all the required Z80 cycles.
--
case FSM_STATE is
when IdleCycle =>
-----------------------------
-- Z80 Fetch Cycle.
-----------------------------
when FetchCycle =>
if(Z80_CLK_RE = '1' or Z80_CLK_LEVEL = '1') then
CPU_T_STATE_SET<= 1;
CPU_T_STATES <= 4;
Z80_M1ni <= '0';
FSM_STATE <= FetchCycle_2;
end if;
when FetchCycle_2 =>
if(Z80_CLK_FE = '1' and CPU_T_STATE = 1) then
Z80_MREQni <= '0';
Z80_RDni <= '0';
FSM_STATE <= FetchCycle_3;
end if;
when FetchCycle_3 =>
if(CPU_T_STATE = 2 and Z80_CLK_FE = '1' and Z80_WAITni = '1') then
FSM_STATE <= FetchCycle_4;
end if;
when FetchCycle_4 =>
-- To meet the timing diagrams, just after Rising edge on T3 clear signals. Data wont be available until
-- a short period before the falling edge of T3 (could be an MZ-700 design restriction or the Z80 timing diagrams are a bit out).
if(CPU_T_STATE = 3 and Z80_CLK_RE = '1' and Z80_WAITni = '1') then
FSM_STATE <= RefreshCycle;
end if;
-----------------------------
-- Z80 Refresh Cycle.
-----------------------------
when RefreshCycle =>
-- Latch data from mainboard.
CPU_DATA_IN <= Z80_DATA;
FSM_STATUS <= '0';
Z80_RFSHni <= '0';
FSM_STATE <= RefreshCycle_1;
when RefreshCycle_1 =>
-- Falling edge of T3 activates the MREQ line.
if(Z80_CLK_FE = '1' and CPU_T_STATE = 3) then
Z80_MREQni <= '0';
FSM_STATE <= RefreshCycle_2;
end if;
when RefreshCycle_2 =>
if(Z80_CLK_FE = '1' and CPU_T_STATE = 4) then
Z80_MREQni <= '1';
end if;
if(Z80_MREQni = '1' and CPU_T_STATE = 4) then
REFRESH_ADDR(6 downto 0) <= REFRESH_ADDR(6 downto 0) + 1;
FSM_STATE <= IdleCycle;
end if;
when RefreshCycle_3 =>
CPU_T_STATE_SET <= 3;
CPU_T_STATES <= 4;
Z80_RFSHni <= '0';
FSM_STATE <= RefreshCycle_1;
-----------------------------
-- Z80 Write Cycle.
-----------------------------
when WriteCycle =>
FSM_STATUS <= '0';
if(Z80_CLK_RE = '1' or Z80_CLK_LEVEL = '1') then
CPU_T_STATE_SET<= 1;
CPU_T_STATES <= 3;
FSM_STATE <= WriteCycle_2;
end if;
when WriteCycle_2 =>
if(Z80_CLK_FE = '1' and CPU_T_STATE = 1) then
Z80_MREQni <= '0';
CPU_DATA_EN <= '1';
FSM_STATE <= WriteCycle_3;
end if;
when WriteCycle_3 =>
if(CPU_T_STATE = 2 and Z80_CLK_FE = '1' and Z80_WAITni = '1') then
Z80_WRni <= '0';
FSM_STATE <= WriteCycle_4;
end if;
when WriteCycle_4 =>
if(CPU_T_STATE = 3 and Z80_CLK_FE = '1' and Z80_WAITni = '1') then
Z80_MREQni <= '1';
Z80_WRni <= '1';
FSM_STATE <= IdleCycle;
end if;
-----------------------------
-- Z80 Read Cycle.
-----------------------------
when ReadCycle =>
if(Z80_CLK_RE = '1' or Z80_CLK_LEVEL = '1') then
CPU_T_STATE_SET<= 1;
CPU_T_STATES <= 3;
FSM_STATE <= ReadCycle_2;
end if;
when ReadCycle_2 =>
if(Z80_CLK_FE = '1' and CPU_T_STATE = 1) then
Z80_MREQni <= '0';
Z80_RDni <= '0';
FSM_STATE <= ReadCycle_3;
end if;
when ReadCycle_3 =>
if(CPU_T_STATE = 2 and Z80_CLK_FE = '1' and Z80_WAITni = '1') then
FSM_STATE <= ReadCycle_4;
end if;
when ReadCycle_4 =>
if(CPU_T_STATE = 3 and Z80_CLK_FE = '1' and Z80_WAITni = '1') then
-- Latch data from mainboard.
CPU_DATA_IN <= Z80_DATA;
FSM_STATUS <= '0';
-- MREQ/RD are deactivated at idle giving 1 clock to latch the data in.
FSM_STATE <= IdleCycle;
end if;
-----------------------------
-- Z80 IO Write Cycle.
-----------------------------
when WriteIOCycle =>
FSM_STATUS <= '0';
if(Z80_CLK_RE = '1' or Z80_CLK_LEVEL = '1') then
CPU_T_STATE_SET<= 1;
CPU_T_STATES <= 4;
FSM_STATE <= WriteIOCycle_2;
end if;
when WriteIOCycle_2 =>
if(Z80_CLK_FE = '1') then
CPU_DATA_EN <= '1';
FSM_STATE <= WriteIOCycle_3;
end if;
when WriteIOCycle_3 =>
if(Z80_CLK_FE = '1' and CPU_T_STATE = 2) then
Z80_IORQni <= '0';
Z80_WRni <= '0';
FSM_STATE <= WriteIOCycle_4;
end if;
when WriteIOCycle_4 =>
-- Add automatic Wait State (called T3 here but actually TW).
if(CPU_T_STATE = 3 and Z80_CLK_FE = '1' and Z80_WAITni = '1') then
FSM_STATE <= WriteIOCycle_5;
end if;
when WriteIOCycle_5 =>
if(CPU_T_STATE = 4 and Z80_CLK_FE = '1' and Z80_WAITni = '1') then
Z80_IORQni <= '1';
Z80_WRni <= '1';
FSM_STATE <= IdleCycle;
end if;
-----------------------------
-- Z80 IO Read Cycle.
-----------------------------
when ReadIOCycle =>
if(Z80_CLK_RE = '1' or Z80_CLK_LEVEL = '1') then
CPU_T_STATE_SET<= 1;
CPU_T_STATES <= 4;
FSM_STATE <= ReadIOCycle_2;
end if;
when ReadIOCycle_2 =>
if(Z80_CLK_FE = '1' and CPU_T_STATE = 2) then
Z80_IORQni <= '0';
Z80_RDni <= '0';
FSM_STATE <= ReadIOCycle_3;
end if;
when ReadIOCycle_3 =>
-- Add automatic Wait State.
if(CPU_T_STATE = 3 and Z80_CLK_FE = '1' and Z80_WAITni = '1') then
CPU_T_STATE_SET<= 2;
FSM_STATE <= ReadIOCycle_4;
end if;
when ReadIOCycle_4 =>
if(CPU_T_STATE = 4 and Z80_CLK_FE = '1' and Z80_WAITni = '1') then
-- Latch data from mainboard.
CPU_DATA_IN <= Z80_DATA;
FSM_STATUS <= '0';
-- IORA/RD are deactivated at idle giving 1 clock to latch the data in.
FSM_STATE <= IdleCycle;
end if;
-----------------------------
-- Halt Request.
-----------------------------
when HaltCycle =>
Z80_HALTni <= '0';
FSM_STATUS <= '0';
FSM_STATE <= IdleCycle;
-----------------------------
-- Z80 Bus Request.
-----------------------------
when BusReqCycle =>
Z80_BUSRQ_ACKni <= '0';
FSM_STATE <= IdleCycle;
end case;
VCPU_CS_EDGE <= VCPU_CS_EDGE(0) & VSOM_SPI_CSn;
end if;
end process;
-- CPU Interface tri-state control based on acknowledged bus request.
Z80_ADDR <= IPAR & REFRESH_ADDR when Z80_RFSHni = '0'
else
CPU_ADDR when Z80_BUSRQ_ACKni = '1'
else
(others => 'Z');
Z80_DATA <= CPU_DATA_OUT when Z80_BUSRQ_ACKni = '1' and CPU_DATA_EN = '1'
else
(others => 'Z');
-- Z80_DATAi <= Z80_DATA when Z80_RDn = '0'
-- else (others => '1');
Z80_RDn <= Z80_RDni when Z80_BUSRQ_ACKni = '1'
else 'Z';
Z80_WRn <= Z80_WRni when Z80_BUSRQ_ACKni = '1'
else 'Z';
Z80_M1n <= Z80_M1ni when Z80_BUSRQ_ACKni = '1'
else 'Z';
Z80_RFSHn <= Z80_RFSHni when Z80_BUSRQ_ACKni = '1'
else 'Z';
Z80_MREQn <= Z80_MREQni when Z80_BUSRQ_ACKni = '1'
else 'Z';
Z80_IORQn <= Z80_IORQni when Z80_BUSRQ_ACKni = '1'
else 'Z';
Z80_BUSAKn <= Z80_BUSRQ_ACKni;
-- CPU Interface single state output.
Z80_HALTn <= Z80_HALTni;
-- CPU Interface single state input.
Z80_NMIni <= Z80_NMIn;
Z80_INTni <= Z80_INTn;
Z80_WAITni <= Z80_WAITn;
Z80_BUSRQni <= Z80_BUSRQn;
-- SOM Reset.
PM_RESET <= PM_RESETi;
-- SOM to CPLD Interface.
VSOM_DATA_OUT <= CPU_DATA_IN when VSOM_HBYTE = '1'
else
FSM_STATUS & RFSH_STATUS & Z80_BUSRQ_ACKni & Z80_BUSRQn & Z80_INTn & Z80_NMIn & Z80_WAITn & Z80_RESETn when VSOM_HBYTE = '0'
else
(others => '0');
-- Loopback test, echo what was received.
SPI_TX_DATA <= SPI_RX_DATA when SPI_LOOPBACK_TEST = '1'
else
CPU_ADDR & CPU_DATA_IN & FSM_STATUS & RFSH_STATUS & Z80_BUSRQ_ACKni & Z80_BUSRQn & Z80_INTn & Z80_NMIn & Z80_WAITn & Z80_RESETn;
-- Signal mirrors.
VSOM_READY <= '0' when FSM_STATUS='1' or SPI_NEW_DATA /= SPI_PROCESSING
else '1'; -- FSM Ready (1), Busy (0)
VSOM_LTSTATE <= '1' when CPU_LAST_T_STATE = '1' -- Last T-State in current cycle.
else '0';
VSOM_BUSRQ <= not Z80_BUSRQn; -- Host device requesting Z80 Bus.
VSOM_BUSACK <= not Z80_BUSRQ_ACKni; -- Host device granted Z80 Bus
VSOM_INT <= not Z80_INTn; -- Z80 INT signal
VSOM_NMI <= not Z80_NMIn; -- Z80 NMI signal
VSOM_WAIT <= not Z80_WAITn; -- Z80 WAIT signal
VSOM_RESET <= not VSOM_RESETni; -- Z80 RESET signal
VSOM_RSV <= (others => '0'); -- Reserved pins.
-- Video/Audio control signals.
VIDEO_SRC <= VIDEO_SRCi;
MONO_VIDEO_SRC <= MONO_VIDEO_SRCi;
AUDIO_SRC_L <= AUDIO_SRC_Li;
AUDIO_SRC_R <= AUDIO_SRC_Ri;
-- USB Power Supply enable.
VBUS_EN <= VBUS_ENi;
-- Monochrome output is based on the incoming VGA to give the best chrominance levels.
MONO_R <= VGA_R;
MONO_G <= VGA_G;
MONO_B <= VGA_B;
-- Blanking is active when all colour signals are at 0. The DAC converts values in range 4v .. 5v to adjust chrominance
-- but true off can obly be achieved by bringing the signal value to 0v which is achieved by a Mux activated with this blanking signal.
MONO_BLANKn <= '0' when VGA_R = "000" and VGA_G = "000" and VGA_B = "000"
else '1';
-- Generate composite sync.
VGA_CSYNCn <= VGA_HSYNCn xor not VGA_VSYNCn;
MONO_CSYNCn <= VGA_HSYNCn xor not VGA_VSYNCn;
-- DAC clocks.
--VGA_PXL_CLK <= CLK_50M;
MONO_PXL_CLK <= VGA_PXL_CLK;
end architecture;

View File

@@ -0,0 +1,222 @@
---------------------------------------------------------------------------------------------------------
--
-- Name: tzpuFusionX_Toplevel.vhd
-- Version: MZ-700
-- Created: June 2020
-- Author(s): Philip Smart
-- Description: tzpuFusionX CPLD Top Level module.
--
-- This module contains the basic pin definition of the CPLD<->logic needed in the
-- project which targets the MZ-700 host.
--
-- Credits:
-- Copyright: (c) 2018-22 Philip Smart <philip.smart@net2net.org>
--
-- History: June 2020 - Snapshot taken from the MZ80A version of the tranZPUter SW-700 source.
--
---------------------------------------------------------------------------------------------------------
-- 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.
--
-- along with this program. If not, see <http:--www.gnu.org-licenses->.
---------------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.tzpuFusionX_pkg.all;
library altera;
use altera.altera_syn_attributes.all;
entity tzpuFusionX_MZ700 is
port (
-- Z80 Address Bus
Z80_ADDR : inout std_logic_vector(15 downto 0);
-- Z80 Data Bus
Z80_DATA : inout std_logic_vector(7 downto 0);
-- Z80 Control signals.
Z80_BUSRQn : in std_logic;
Z80_BUSAKn : out std_logic;
Z80_INTn : in std_logic;
Z80_IORQn : inout std_logic;
Z80_MREQn : inout std_logic;
Z80_NMIn : in std_logic;
Z80_RDn : inout std_logic;
Z80_WRn : inout std_logic;
Z80_RESETn : in std_logic; -- Host CPU Reset signal, also CPLD reset.
Z80_HALTn : out std_logic;
Z80_WAITn : in std_logic;
Z80_M1n : inout std_logic;
Z80_RFSHn : inout std_logic;
-- SOM SPI
VSOM_SPI_CSn : in std_logic; -- SPI Slave Select
VSOM_SPI_CLK : in std_logic; -- SPI Clock
VSOM_SPI_MOSI : in std_logic; -- SPI Master Output Slave Input
VSOM_SPI_MISO : out std_logic; -- SPI Master Input Slave Output
-- SOM Parallel Bus.
VSOM_DATA_OUT : out std_logic_vector(7 downto 0); -- Address/Data bus for CPLD control registers.
VSOM_HBYTE : in std_logic; -- Parallel Bus High (1)/Low (0) byte.
VSOM_READY : out std_logic; -- FSM Ready (1), Busy (0)
VSOM_LTSTATE : out std_logic; -- Last T-State in current cycle, 1 = active.
VSOM_BUSRQ : out std_logic; -- Host device requesting Z80 Bus.
VSOM_BUSACK : out std_logic; -- Host device granted Z80 Bus
VSOM_INT : out std_logic; -- Z80 INT signal
VSOM_NMI : out std_logic; -- Z80 NMI signal
VSOM_WAIT : out std_logic; -- Z80 WAIT signal
VSOM_RESET : out std_logic; -- Z80 RESET signal
VSOM_RSV : out std_logic_vector(1 downto 1); -- Reserved pins.
-- SOM Control Signals
PM_RESET : out std_logic; -- Reset SOM
-- VGA_Palette Control
VGA_R : in std_logic_vector(9 downto 7); -- Signals used for detecting blank or no video output.
VGA_G : in std_logic_vector(9 downto 7);
VGA_B : in std_logic_vector(9 downto 8);
-- VGA Control Signals
VGA_PXL_CLK : in std_logic; -- VGA Pixel clock for DAC conversion.
VGA_DISPEN : in std_logic; -- Displayed Enabled (SOM video output).
VGA_VSYNCn : in std_logic; -- SOM VSync.
VGA_HSYNCn : in std_logic; -- SOM HSync.
VGA_COLR : out std_logic; -- COLR colour carrier frequency.
VGA_CSYNCn : out std_logic; -- VGA Composite Sync.
VGA_BLANKn : out std_logic; -- VGA Blank detected.
-- CRT Control Signals
MONO_PXL_CLK : out std_logic; -- Mono CRT pixel clock for DAC conversion.
MONO_BLANKn : out std_logic; -- Mono CRT Blank (no active pixel) detection.
MONO_CSYNCn : out std_logic; -- Mono CRT composite sync.
MONO_RSV : out std_logic;
-- CRT Lower Chrominance Control
MONO_R : out std_logic_vector(2 downto 0); -- Signals to fine tune Red level of monochrome chrominance.
MONO_G : out std_logic_vector(2 downto 0); -- Signals to fine tune Green level of monochrome chrominance.
MONO_B : out std_logic_vector(2 downto 1); -- Signals to fine tune Blue level of monochrome chrominance.
-- MUX Control Signals
VIDEO_SRC : out std_logic; -- Select video source, Mainboard or SOM.
MONO_VIDEO_SRC : out std_logic; -- Select crt video source, Mainboard or SOM.
AUDIO_SRC_L : out std_logic; -- Select Audio Source Left Channel, Mainboard or SOM.
AUDIO_SRC_R : out std_logic; -- Select Audio Source Right Channel, Mainboard or SOM.
-- Mainboard Reset Signals
MB_RESETn : in std_logic; -- Motherboard Reset pressed.
MB_IPLn : in std_logic; -- Motherboard IPL pressed.
-- USB Power Control
VBUS_EN : out std_logic; -- USB Enable Power Output
-- Clocks.
Z80_CLK : in std_logic; -- Host CPU Clock
CLK_50M : in std_logic -- 50MHz oscillator.
);
END entity;
architecture rtl of tzpuFusionX_MZ700 is
begin
cpldl512Toplevel : entity work.cpld512
generic map (
SPI_CLK_POLARITY => '0'
)
port map
(
-- Z80 Address Bus
Z80_ADDR => Z80_ADDR,
-- Z80 Data Bus
Z80_DATA => Z80_DATA,
-- Z80 Control signals.
Z80_BUSRQn => Z80_BUSRQn,
Z80_BUSAKn => Z80_BUSAKn,
Z80_INTn => Z80_INTn,
Z80_IORQn => Z80_IORQn,
Z80_MREQn => Z80_MREQn,
Z80_NMIn => Z80_NMIn,
Z80_RDn => Z80_RDn,
Z80_WRn => Z80_WRn,
Z80_RESETn => Z80_RESETn,
Z80_HALTn => Z80_HALTn,
Z80_WAITn => Z80_WAITn,
Z80_M1n => Z80_M1n,
Z80_RFSHn => Z80_RFSHn,
-- SOM SPI
VSOM_SPI_CSn => VSOM_SPI_CSn, -- SPI Slave Select
VSOM_SPI_CLK => VSOM_SPI_CLK, -- SPI Clock
VSOM_SPI_MOSI => VSOM_SPI_MOSI, -- SPI Master Output Slave Input
VSOM_SPI_MISO => VSOM_SPI_MISO, -- SPI Master Input Slave Output
-- SOM Parallel Bus.
VSOM_DATA_OUT => VSOM_DATA_OUT, -- Address/Data bus for CPLD control registers.
VSOM_HBYTE => VSOM_HBYTE, -- Parallel Bus High (1)/Low (0) byte.
VSOM_READY => VSOM_READY, -- FSM Ready (1), Busy (0)
VSOM_LTSTATE => VSOM_LTSTATE, -- Last T-State in current cycle.
VSOM_BUSRQ => VSOM_BUSRQ, -- Host device requesting Z80 Bus.
VSOM_BUSACK => VSOM_BUSACK, -- Host device granted Z80 Bus
VSOM_INT => VSOM_INT, -- Z80 INT signal
VSOM_NMI => VSOM_NMI, -- Z80 NMI signal
VSOM_WAIT => VSOM_WAIT, -- Z80 WAIT signal
VSOM_RESET => VSOM_RESET, -- Z80 RESET signal
VSOM_RSV => VSOM_RSV, -- Reserved pins.
-- SOM Control Signals
PM_RESET => PM_RESET, -- Reset SOM
-- VGA_Palette Control
VGA_R => VGA_R, -- Signals used for detecting blank or no video output.
VGA_G => VGA_G,
VGA_B => VGA_B,
-- VGA Control Signals
VGA_PXL_CLK => VGA_PXL_CLK, -- VGA Pixel clock for DAC conversion.
VGA_DISPEN => VGA_DISPEN, -- Displayed Enabled (SOM video output).
VGA_VSYNCn => VGA_VSYNCn, -- SOM VSync.
VGA_HSYNCn => VGA_HSYNCn, -- SOM HSync.
VGA_COLR => VGA_COLR, -- COLR colour carrier frequency.
VGA_CSYNCn => VGA_CSYNCn, -- VGA Composite Sync.
VGA_BLANKn => VGA_BLANKn, -- VGA Blank detected.
-- CRT Control Signals
MONO_PXL_CLK => MONO_PXL_CLK, -- Mono CRT pixel clock for DAC conversion.
MONO_BLANKn => MONO_BLANKn, -- Mono CRT Blank (no active pixel) detection.
MONO_CSYNCn => MONO_CSYNCn, -- Mono CRT composite sync.
MONO_RSV => MONO_RSV,
-- CRT Lower Chrominance Control
MONO_R => MONO_R, -- Signals to fine tune Red level of monochrome chrominance.
MONO_G => MONO_G, -- Signals to fine tune Green level of monochrome chrominance.
MONO_B => MONO_B, -- Signals to fine tune Blue level of monochrome chrominance.
-- MUX Control Signals
VIDEO_SRC => VIDEO_SRC, -- Select video source, Mainboard or SOM.
MONO_VIDEO_SRC => MONO_VIDEO_SRC, -- Select crt video source, Mainboard or SOM.
AUDIO_SRC_L => AUDIO_SRC_L, -- Select Audio Source Left Channel, Mainboard or SOM.
AUDIO_SRC_R => AUDIO_SRC_R, -- Select Audio Source Right Channel, Mainboard or SOM.
-- Mainboard Reset Signals=> MONO_R,
MB_RESETn => MB_RESETn, -- Motherboard Reset pressed.
MB_IPLn => MB_IPLn, -- Motherboard IPL pressed.
-- USB Power Control
VBUS_EN => VBUS_EN, -- USB Enable Power Output
-- Clocks.
Z80_CLK => Z80_CLK, -- Host CPU Clock
CLK_50M => CLK_50M -- 50MHz oscillator.
);
end architecture;

View File

@@ -0,0 +1,221 @@
---------------------------------------------------------------------------------------------------------
--
-- Name: tzpuFusionX_pkg.vhd
-- Created: June 2020
-- Author(s): Philip Smart
-- Description: tzpuFusionX CPLD configuration file.
--
-- This module contains parameters for the CPLD in the tzpuFusionX project
-- which targets the MZ-700 host.
--
-- Credits:
-- Copyright: (c) 2018-22 Philip Smart <philip.smart@net2net.org>
--
-- History: June 2020 - Snapshot taken from the MZ700 version of the tranZPUter SW-700 source.
--
---------------------------------------------------------------------------------------------------------
-- 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->.
---------------------------------------------------------------------------------------------------------
library ieee;
library pkgs;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
package tzpuFusionX_pkg is
------------------------------------------------------------
-- Constants
------------------------------------------------------------
-- Potential logic state constants.
constant YES : std_logic := '1';
constant NO : std_logic := '0';
constant HI : std_logic := '1';
constant LO : std_logic := '0';
constant ONE : std_logic := '1';
constant ZERO : std_logic := '0';
constant HIZ : std_logic := 'Z';
-- CPLD Command instructions.
constant CPLD_CMD_RESET_HOST : integer := 1;
constant CPLD_CMD_HOLD_HOST_BUS : integer := 2;
constant CPLD_CMD_RELEASE_HOST_BUS: integer := 3;
-- Target hardware modes.
constant MODE_MZ80K : integer := 0;
constant MODE_MZ80C : integer := 1;
constant MODE_MZ1200 : integer := 2;
constant MODE_MZ80A : integer := 3;
constant MODE_MZ700 : integer := 4;
constant MODE_MZ800 : integer := 5;
constant MODE_MZ80B : integer := 6;
constant MODE_MZ2000 : integer := 7;
-- Memory management modes.
constant TZMM_ORIG : integer := 00; -- Original Sharp mode, no tranZPUter features are selected except the I/O control registers (default: 0x60-063).
constant TZMM_BOOT : integer := 01; -- Original mode but E800-EFFF is mapped to tranZPUter RAM so TZFS can be booted.
constant TZMM_TZFS : integer := 02; -- TZFS main memory configuration. all memory is in tranZPUter RAM, E800-FFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected.
constant TZMM_TZFS2 : integer := 03; -- TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 1.
constant TZMM_TZFS3 : integer := 04; -- TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 2.
constant TZMM_TZFS4 : integer := 05; -- TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 3.
constant TZMM_CPM : integer := 06; -- CPM main memory configuration, all memory on the tranZPUter board, 64K block 4 selected. Special case for F3C0:F3FF & F7C0:F7FF (floppy disk paging vectors) which resides on the mainboard.
constant TZMM_CPM2 : integer := 07; -- CPM main memory configuration, F000-FFFF are on the tranZPUter board in block 4, 0040-CFFF and E800-EFFF are in block 5, mainboard for D000-DFFF (video), E000-E800 (Memory control) selected.
-- Special case for 0000:003F (interrupt vectors) which resides in block 4, F3FE:F3FF & F7FE:F7FF (floppy disk paging vectors) which resides on the mainboard.
constant TZMM_COMPAT : integer := 08; -- Compatibility monitor mode, monitor ROM on mainboard, RAM on tranZPUter in Block 0 1000-CFFF.
constant TZMM_HOSTACCESS : integer := 09; -- Monitor ROM 0000-0FFF and Main DRAM 0x1000-0xD000, video and memory mapped I/O are on the host machine, User/Floppy ROM E800-FFFF are in tranZPUter memory.
constant TZMM_MZ700_0 : integer := 10; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the mainboard.
constant TZMM_MZ700_1 : integer := 11; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
constant TZMM_MZ700_2 : integer := 12; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
constant TZMM_MZ700_3 : integer := 13; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
constant TZMM_MZ700_4 : integer := 14; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
constant TZMM_MZ800 : integer := 15; -- MZ800 Mode - Running on MZ800 hardware, configuration set according to MZ700/MZ800 mode.
constant TZMM_MZ2000 : integer := 16; -- MZ2000 Mode - Running on MZ2000 hardware, configuration set according to runtime configuration registers.
constant TZMM_FPGA : integer := 21; -- Open up access for the K64F to the FPGA resources such as memory. All other access to RAM or mainboard is blocked.
constant TZMM_TZPUM : integer := 22; -- Everything in on mainboard, no access to tranZPUter memory.
constant TZMM_TZPU : integer := 23; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
constant TZMM_TZPU0 : integer := 24; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
constant TZMM_TZPU1 : integer := 25; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 1 is selected.
constant TZMM_TZPU2 : integer := 26; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 2 is selected.
constant TZMM_TZPU3 : integer := 27; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 3 is selected.
constant TZMM_TZPU4 : integer := 28; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 4 is selected.
constant TZMM_TZPU5 : integer := 29; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 5 is selected.
constant TZMM_TZPU6 : integer := 30; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 6 is selected.
constant TZMM_TZPU7 : integer := 31; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 7 is selected.
------------------------------------------------------------
-- Configurable parameters.
------------------------------------------------------------
-- Target hardware.
constant CPLD_HOST_HW : integer := MODE_MZ700;
-- Target video hardware.
constant CPLD_HAS_FPGA_VIDEO : std_logic := '1';
-- Version of hdl.
constant CPLD_VERSION : integer := 2;
-- Clock source for the secondary clock. If a K64F is installed then enable it otherwise use the onboard oscillator.
--
constant USE_K64F_CTL_CLOCK : integer := 1;
------------------------------------------------------------
-- Function prototypes
------------------------------------------------------------
-- Find the maximum of two integers.
function IntMax(a : in integer; b : in integer) return integer;
-- Find the number of bits required to represent an integer.
function log2ceil(arg : positive) return natural;
-- Function to calculate the number of whole 'clock' cycles in a given time period, the period being in ns.
function clockTicks(period : in integer; clock : in integer) return integer;
-- Function to reverse the order of the bits in a standard logic vector.
-- ie. 1010 becomes 0101
function reverse_vector(slv:std_logic_vector) return std_logic_vector;
-- Function to convert an integer (0 or 1) into std_logic.
--
function to_std_logic(i : in integer) return std_logic;
-- Function to return the value of a bit as an integer for array indexing etc.
function bit_to_integer( s : std_logic ) return natural;
------------------------------------------------------------
-- Records
------------------------------------------------------------
------------------------------------------------------------
-- Components
------------------------------------------------------------
end tzpuFusionX_pkg;
------------------------------------------------------------
-- Function definitions.
------------------------------------------------------------
package body tzpuFusionX_pkg is
-- Find the maximum of two integers.
function IntMax(a : in integer; b : in integer) return integer is
begin
if a > b then
return a;
else
return b;
end if;
return a;
end function IntMax;
-- Find the number of bits required to represent an integer.
function log2ceil(arg : positive) return natural is
variable tmp : positive := 1;
variable log : natural := 0;
begin
if arg = 1 then
return 0;
end if;
while arg > tmp loop
tmp := tmp * 2;
log := log + 1;
end loop;
return log;
end function;
-- Function to calculate the number of whole 'clock' cycles in a given time period, the period being in ns.
function clockTicks(period : in integer; clock : in integer) return integer is
variable ticks : real;
variable fracTicks : real;
begin
ticks := (Real(period) * Real(clock)) / 1000000000.0;
fracTicks := ticks - CEIL(ticks);
if fracTicks > 0.0001 then
return Integer(CEIL(ticks + 1.0));
else
return Integer(CEIL(ticks));
end if;
end function;
function reverse_vector(slv:std_logic_vector) return std_logic_vector is
variable target : std_logic_vector(slv'high downto slv'low);
begin
for idx in slv'high downto slv'low loop
target(idx) := slv(slv'low + (slv'high-idx));
end loop;
return target;
end reverse_vector;
function to_std_logic(i : in integer) return std_logic is
begin
if i = 0 then
return '0';
end if;
return '1';
end function;
-- Function to return the value of a bit as an integer for array indexing etc.
function bit_to_integer( s : std_logic ) return natural is
begin
if s = '1' then
return 1;
else
return 0;
end if;
end function;
end package body;

View File

@@ -0,0 +1,30 @@
# -------------------------------------------------------------------------- #
#
# 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.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition
# Date created = 16:29:32 June 24, 2020
#
# -------------------------------------------------------------------------- #
QUARTUS_VERSION = "13.0"
DATE = "16:29:32 September 10, 2021"
# Revisions
PROJECT_REVISION = "tzpuFusionX_MZ80A"

View File

@@ -0,0 +1,243 @@
# -------------------------------------------------------------------------- #
#
# 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.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition
# Date created = 16:29:32 June 24, 2020
#
# -------------------------------------------------------------------------- #
#
# Notes:
#
# 1) The default values for assignments are stored in the file:
# tzpuFusionX.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.
#
# -------------------------------------------------------------------------- #
set_global_assignment -name FAMILY MAX7000AE
set_global_assignment -name DEVICE "EPM7512AETC144-10"
set_global_assignment -name TOP_LEVEL_ENTITY tzpuFusionX_MZ80A
set_global_assignment -name ORIGINAL_QUARTUS_VERSION "13.0 SP1"
set_global_assignment -name PROJECT_CREATION_TIME_DATE "16:29:32 JUNE 24, 2020"
set_global_assignment -name LAST_QUARTUS_VERSION "13.0 SP1"
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR "-1"
set_global_assignment -name EDA_DESIGN_ENTRY_SYNTHESIS_TOOL "<None>"
set_global_assignment -name EDA_INPUT_VCC_NAME VCC -section_id eda_design_synthesis
set_global_assignment -name EDA_INPUT_DATA_FORMAT EDIF -section_id eda_design_synthesis
set_global_assignment -name EDA_SIMULATION_TOOL "ModelSim-Altera (VHDL)"
set_global_assignment -name EDA_OUTPUT_DATA_FORMAT VHDL -section_id eda_simulation
set_global_assignment -name OPTIMIZE_HOLD_TIMING OFF
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING OFF
set_global_assignment -name FITTER_EFFORT "STANDARD FIT"
set_global_assignment -name MAX7000_DEVICE_IO_STANDARD LVTTL
# Z80 Data Bus
# ============
set_location_assignment PIN_81 -to Z80_DATA[0]
set_location_assignment PIN_78 -to Z80_DATA[1]
set_location_assignment PIN_87 -to Z80_DATA[2]
set_location_assignment PIN_100 -to Z80_DATA[3]
set_location_assignment PIN_102 -to Z80_DATA[4]
set_location_assignment PIN_93 -to Z80_DATA[5]
set_location_assignment PIN_94 -to Z80_DATA[6]
set_location_assignment PIN_84 -to Z80_DATA[7]
# Z80 Control signals.
# ====================
set_location_assignment PIN_69 -to Z80_INTn
set_location_assignment PIN_70 -to Z80_NMIn
set_location_assignment PIN_71 -to Z80_HALTn
set_location_assignment PIN_68 -to Z80_MREQn
set_location_assignment PIN_65 -to Z80_IORQn
set_location_assignment PIN_67 -to Z80_RDn
set_location_assignment PIN_66 -to Z80_WRn
set_location_assignment PIN_63 -to Z80_BUSAKn
set_location_assignment PIN_62 -to Z80_WAITn
set_location_assignment PIN_61 -to Z80_BUSRQn
set_location_assignment PIN_79 -to Z80_RFSHn
set_location_assignment PIN_60 -to Z80_M1n
set_location_assignment PIN_56 -to Z80_RESETn
set_location_assignment PIN_101 -to Z80_CLK
# Z80 Address Bus
# ===============
set_location_assignment PIN_80 -to Z80_ADDR[0]
set_location_assignment PIN_90 -to Z80_ADDR[1]
set_location_assignment PIN_83 -to Z80_ADDR[2]
set_location_assignment PIN_86 -to Z80_ADDR[3]
set_location_assignment PIN_88 -to Z80_ADDR[4]
set_location_assignment PIN_91 -to Z80_ADDR[5]
set_location_assignment PIN_92 -to Z80_ADDR[6]
set_location_assignment PIN_96 -to Z80_ADDR[7]
set_location_assignment PIN_97 -to Z80_ADDR[8]
set_location_assignment PIN_98 -to Z80_ADDR[9]
set_location_assignment PIN_99 -to Z80_ADDR[10]
set_location_assignment PIN_110 -to Z80_ADDR[11]
set_location_assignment PIN_108 -to Z80_ADDR[12]
set_location_assignment PIN_107 -to Z80_ADDR[13]
set_location_assignment PIN_106 -to Z80_ADDR[14]
set_location_assignment PIN_103 -to Z80_ADDR[15]
# SOM SPI
# =======
set_location_assignment PIN_32 -to VSOM_SPI_CSn
set_location_assignment PIN_31 -to VSOM_SPI_CLK
set_location_assignment PIN_30 -to VSOM_SPI_MOSI
set_location_assignment PIN_29 -to VSOM_SPI_MISO
# SOM Parallel Bus
# ================
set_location_assignment PIN_41 -to VSOM_DATA_OUT[0]
set_location_assignment PIN_40 -to VSOM_DATA_OUT[1]
set_location_assignment PIN_39 -to VSOM_DATA_OUT[2]
set_location_assignment PIN_38 -to VSOM_DATA_OUT[3]
set_location_assignment PIN_37 -to VSOM_DATA_OUT[4]
set_location_assignment PIN_36 -to VSOM_DATA_OUT[5]
set_location_assignment PIN_35 -to VSOM_DATA_OUT[6]
set_location_assignment PIN_34 -to VSOM_DATA_OUT[7]
set_location_assignment PIN_132 -to VSOM_HBYTE
# SOM Reserved signals.
# =====================
set_location_assignment PIN_21 -to VSOM_RSV[1]
# SOM Control Signals
# ===================
set_location_assignment PIN_28 -to VSOM_READY
set_location_assignment PIN_18 -to VSOM_LTSTATE
set_location_assignment PIN_27 -to VSOM_BUSRQ
set_location_assignment PIN_26 -to VSOM_BUSACK
set_location_assignment PIN_19 -to VSOM_INT
set_location_assignment PIN_22 -to VSOM_NMI
set_location_assignment PIN_25 -to VSOM_WAIT
set_location_assignment PIN_23 -to VSOM_RESET
set_location_assignment PIN_16 -to PM_RESET
# VGA_Palette Control
# ===================
set_location_assignment PIN_133 -to VGA_R[7]
set_location_assignment PIN_137 -to VGA_R[8]
set_location_assignment PIN_140 -to VGA_R[9]
set_location_assignment PIN_134 -to VGA_G[7]
set_location_assignment PIN_138 -to VGA_G[8]
set_location_assignment PIN_141 -to VGA_G[9]
set_location_assignment PIN_136 -to VGA_B[8]
set_location_assignment PIN_139 -to VGA_B[9]
# VGA Control Signals
# ===================
set_location_assignment PIN_142 -to VGA_PXL_CLK
set_location_assignment PIN_14 -to VGA_DISPEN
set_location_assignment PIN_12 -to VGA_VSYNCn
set_location_assignment PIN_11 -to VGA_HSYNCn
set_location_assignment PIN_82 -to VGA_COLR
set_location_assignment PIN_109 -to VGA_CSYNCn
set_location_assignment PIN_143 -to VGA_BLANKn
# CRT Control Signals
# ===================
set_location_assignment PIN_15 -to MONO_PXL_CLK
set_location_assignment PIN_114 -to MONO_BLANKn
set_location_assignment PIN_113 -to MONO_CSYNCn
set_location_assignment PIN_116 -to MONO_RSV
# CRT Lower Chrominance Control
# =============================
set_location_assignment PIN_1 -to MONO_R[0]
set_location_assignment PIN_6 -to MONO_R[1]
set_location_assignment PIN_10 -to MONO_R[2]
set_location_assignment PIN_2 -to MONO_G[0]
set_location_assignment PIN_7 -to MONO_G[1]
set_location_assignment PIN_9 -to MONO_G[2]
set_location_assignment PIN_5 -to MONO_B[1]
set_location_assignment PIN_8 -to MONO_B[2]
# MUX Control Signals
# ===================
set_location_assignment PIN_72 -to VIDEO_SRC
set_location_assignment PIN_74 -to MONO_VIDEO_SRC
set_location_assignment PIN_77 -to AUDIO_SRC_L
set_location_assignment PIN_75 -to AUDIO_SRC_R
# Mainboard Reset Signals
# =======================
#set_location_assignment PIN_127 -to CPU_RESETn
set_location_assignment PIN_122 -to MB_RESETn
set_location_assignment PIN_111 -to MB_IPLn
# USB Power Control
# =================
set_location_assignment PIN_55 -to VBUS_EN
# Clocks
# ======
#set_location_assignment PIN_125 -to CPU_CLK
set_location_assignment PIN_128 -to CLK_50M
# Unused ports
# ============
#set_location_assignment PIN_42 -to
#set_location_assignment PIN_43 -to
#set_location_assignment PIN_44 -to
#set_location_assignment PIN_45 -to
#set_location_assignment PIN_112 -to
#set_location_assignment PIN_131 -to
#set_location_assignment PIN_117 -to
#set_location_assignment PIN_118 -to
#set_location_assignment PIN_119 -to
#set_location_assignment PIN_120 -to
#set_location_assignment PIN_121 -to
#set_location_assignment PIN_25 -to
#set_location_assignment PIN_53 -to
#set_location_assignment PIN_128 -to
#set_location_assignment PIN_47 -to
#set_location_assignment PIN_54 -to
#set_location_assignment PIN_127 -to
#set_location_assignment PIN_125 -to
#set_location_assignment PIN_48 -to
#set_location_assignment PIN_46 -to
#set_location_assignment PIN_49 -to
set_global_assignment -name VHDL_FILE ../tzpuFusionX_Toplevel.vhd
set_global_assignment -name VHDL_FILE ../tzpuFusionX_pkg.vhd
set_global_assignment -name VHDL_FILE ../tzpuFusionX.vhd
set_global_assignment -name SDC_FILE tzpuFusionX_MZ80A_constraints.sdc
set_global_assignment -name VHDL_INPUT_VERSION VHDL_2008
set_global_assignment -name VHDL_SHOW_LMF_MAPPING_MESSAGES OFF
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS OFF
set_global_assignment -name MAX7000_OPTIMIZATION_TECHNIQUE AREA
set_global_assignment -name AUTO_RESOURCE_SHARING OFF
set_global_assignment -name PRE_MAPPING_RESYNTHESIS OFF
set_global_assignment -name USE_LOGICLOCK_CONSTRAINTS_IN_BALANCING OFF
set_global_assignment -name INFER_RAMS_FROM_RAW_LOGIC OFF
set_global_assignment -name AUTO_LCELL_INSERTION ON
set_global_assignment -name CDF_FILE output_files/tzpuFusionX_MZ80A.cdf

View File

@@ -0,0 +1,324 @@
## Generated SDC file "tzpuFusionX.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.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition"
## DATE "Fri Jun 26 22:10:05 2020"
##
## DEVICE "EPM7160STC100-10"
##
#**************************************************************
# Time Information
#**************************************************************
set_time_format -unit ns -decimal_places 3
#**************************************************************
# Create Clock
#**************************************************************
# Standard mainboard clock. If using tzpuFusionX on a different host then set to the host frequency.
create_clock -name {Z80_CLK} -period 500.000 -waveform { 0.000 250.000 } [get_ports { Z80_CLK }]
# For 50MHz crystal.
create_clock -name {CLK_50M} -period 20.000 -waveform { 0.000 10.000 } [ get_ports { CLK_50M }]
# For SPI CSn
#create_clock -name {VSOM_SPI_CSn} -period 200.000 -waveform { 160.000 40.000 } [ get_ports { VSOM_SPI_CSn }]
# For SPI CLK
create_clock -name {VSOM_SPI_CLK} -period 14.000 -waveform { 0.000 7.000 } [ get_ports { VSOM_SPI_CLK }]
# For basic board with oscillator.
#create_clock -name {CTLCLK} -period 20.000 -waveform { 0.000 10.000 } [ get_ports { CTLCLK }]
#create_clock -name {cpld512:cpldl512Toplevel|CTLCLKi} -period 280.000 -waveform { 0.000 140.000 } [ get_keepers {cpld512:cpldl512Toplevel|CTLCLKi} ]
##create_clock -name {Z80_CLK} -period 50.000 -waveform { 0.000 25.000 } [get_ports { CTLCLK }]
#**************************************************************
# Create Generated Clock
#**************************************************************
#**************************************************************
# Set Clock Latency
#**************************************************************
#**************************************************************
# Set Clock Uncertainty
#**************************************************************
#derive_clock_uncertainty
#**************************************************************
# Set Input Delay
#**************************************************************
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CTL_MBSEL}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CTL_BUSRQn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CTL_WAITn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {SYS_BUSRQn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {SYS_WAITn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_ADDR[*]}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_HI_ADDR[*]}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {VZ80_ADDR[*]}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_BUSACKn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_DATA[*]}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_HALTn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_IORQn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_M1n}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_MREQn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_RESETn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_RFSHn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_WRn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_RDn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {R_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {G_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {B_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {COLR_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CSYNC_IN}]
##set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CVIDEO_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {HSYNC_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {VSYNC_IN}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {VZ80_DATA[*]}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_MREQn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_IORQn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_WRn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_RDn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_M1n}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_BUSACKn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_INTn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_NMIn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_WAITn}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VWAITn_A21_V_CSYNC}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A20_RFSHn_V_HSYNC}]
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A19_HALTn_V_VSYNC}]
#**************************************************************
# Set Output Delay
#**************************************************************
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {CTL_BUSACKn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {CTL_HALTn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {CTL_M1n}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {CTL_RFSHn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {RAM_CSn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {RAM_CS2n}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {RAM_OEn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {RAM_WEn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {SVCREQn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {SYS_BUSACKn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_BUSRQn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_DATA[*]}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_ADDR[*]}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_HI_ADDR[*]}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_RA_ADDR[*]}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_WAITn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_MREQn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_CLK}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_ADDR[*]}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_DATA[*]}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_CLK}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_MREQn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_IORQn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_RDn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_WRn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_M1n}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VIDEO_RDn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VIDEO_WRn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A18_INTn_V_R}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_BUSRQn_V_G}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A16_WAITn_V_B}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A17_NMIn_V_COLR}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VWAITn_A21_V_CSYNC}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A20_RFSHn_V_HSYNC}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A19_HALTn_V_VSYNC}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_HALTn}]
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_RFSHn}]
# For K64F
#set_output_delay -add_delay -clock [get_clocks {CTLCLK}] 5.000 [get_ports {Z80_CLK}]
# For basic board with oscillator.
#set_output_delay -add_delay -clock [get_clocks {cpld512:cpldl512Toplevel|CTLCLKi}] 5.000 [get_ports {Z80_CLK}]
#**************************************************************
# Set Max Delay
#**************************************************************
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_HALTn} 30.000
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_IORQn} 30.000
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_M1n} 30.000
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_RDn} 30.000
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_WRn} 30.000
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_RFSHn} 30.000
#set_max_delay -from [get_ports {VZ80_A19_HALTn_V_VSYNC}] -to {Z80_HALTn} 30.000
#set_max_delay -from [get_ports {VZ80_IORQn}] -to {Z80_IORQn} 30.000
#set_max_delay -from [get_ports {VZ80_MREQn}] -to {Z80_IORQn} 30.000
#set_max_delay -from [get_ports {VZ80_M1n}] -to {Z80_M1n} 30.000
#set_max_delay -from [get_ports {VZ80_RDn}] -to {Z80_RDn} 30.000
#set_max_delay -from [get_ports {VZ80_WRn}] -to {Z80_WRn} 30.000
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_HALTn} 40.000
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_RFSHn} 40.000
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_IORQn} 40.000
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_M1n} 30.000
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_RDn} 30.000
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_WRn} 30.000
#set_max_delay -from [get_ports {VZ80_A20_RFSHn_V_HSYNC}] -to {Z80_RFSHn} 30.000
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_HALTn} 30.000
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_IORQn} 30.000
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_M1n} 30.000
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_RDn} 30.000
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_WRn} 30.000
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_RFSHn} 30.000
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_HALTn}] 45.000
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_IORQn}] 30.000
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_M1n}] 30.000
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_RDn}] 30.000
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_RFSHn}] 45.000
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_WRn}] 30.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_HALTn}] 45.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_IORQn}] 50.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_M1n}] 40.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_RDn}] 40.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_WRn}] 40.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_RFSHn}] 45.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_HALTn}] 60.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_IORQn}] 45.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_M1n}] 40.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_RDn}] 40.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_WRn}] 40.000
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_RFSHn}] 60.000
#**************************************************************
# Set Min Delay
#**************************************************************
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_HALTn} 1.000
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_IORQn} 1.000
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_M1n} 1.000
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_RDn} 1.000
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_WRn} 1.000
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_RFSHn} 1.000
#set_min_delay -from [get_ports {VZ80_A19_HALTn_V_VSYNC}] -to {Z80_HALTn} 1.000
#set_min_delay -from [get_ports {VZ80_IORQn}] -to {Z80_IORQn} 1.000
#set_min_delay -from [get_ports {VZ80_MREQn}] -to {Z80_IORQn} 1.000
#set_min_delay -from [get_ports {VZ80_M1n}] -to {Z80_M1n} 1.000
#set_min_delay -from [get_ports {VZ80_RDn}] -to {Z80_RDn} 1.000
#set_min_delay -from [get_ports {VZ80_WRn}] -to {Z80_WRn} 1.000
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_HALTn} 1.000
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_RFSHn} 1.000
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_IORQn} 1.000
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_M1n} 1.000
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_RDn} 1.000
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_WRn} 1.000
#set_min_delay -from [get_ports {VZ80_A20_RFSHn_V_HSYNC}] -to {Z80_RFSHn} 1.000
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_HALTn} 1.000
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_IORQn} 1.000
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_M1n} 1.000
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_RDn} 1.000
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_WRn} 1.000
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_RFSHn} 1.000
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_HALTn}] 1.000
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_IORQn}] 1.000
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_M1n}] 1.000
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_RDn}] 1.000
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_RFSHn}] 1.000
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_WRn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_HALTn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_IORQn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_M1n}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_RDn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_WRn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_RFSHn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_HALTn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_IORQn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_M1n}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_RDn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_WRn}] 1.000
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_RFSHn}] 1.000
#**************************************************************
# Set Clock Groups
#**************************************************************
#**************************************************************
# Set False Path
#**************************************************************
# For K64F
#set_false_path -from [get_clocks {CTLCLK}] -to [get_clocks {SYSCLK}]
#set_false_path -from [get_clocks {SYSCLK}] -to [get_clocks {CTLCLK}]
# For basic board with oscillator.
#set_false_path -from [get_clocks {cpld512:cpldl512Toplevel|CTLCLKi}] -to [get_clocks {SYSCLK}]
#set_false_path -from [get_clocks {cpld512:cpldl512Toplevel|CTLCLKi}] -to [get_clocks {CTLCLK}]
#set_false_path -from [get_clocks {SYSCLK}] -to [get_clocks {cpld512:cpldl512Toplevel|CTLCLKi}]
#set_false_path -from [get_clocks {SYSCLK}] -to [get_clocks {CTLCLK}]
# For both configurations.
#set_false_path -from {cpld512:cpldl512Toplevel|KEY_SUBSTITUTE} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|MZ80B_VRAM_HI_ADDR} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|MZ80B_VRAM_LO_ADDR} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|MODE_VIDEO_MZ80B} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#set_false_path -from {cpld512:cpldl512Toplevel|GRAM_PAGE_ENABLE} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
#**************************************************************
# Set Multicycle Path
#**************************************************************
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CTL_BUSRQni} -to {cpld512:cpldl512Toplevel|CTLCLK_Q} -setup -end 2
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CTL_BUSRQni} -to {cpld512:cpldl512Toplevel|CTLCLK_Q} -hold -end 1
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CTL_BUSRQni} -to {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -setup -end 2
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CTL_BUSRQni} -to {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -hold -end 1
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -setup -end 2
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -hold -end 1
#**************************************************************
# Set Maximum Delay
#**************************************************************
#**************************************************************
# Set Minimum Delay
#**************************************************************
#**************************************************************
# Set Input Transition
#**************************************************************

View File

@@ -0,0 +1,982 @@
-------------------------------------------------------------------------------------------------------
--
-- Name: tzpuFusionX.vhd
-- Version: MZ-80A
-- Created: Nov 2022
-- Author(s): Philip Smart
-- Description: tzpuFusionX CPLD logic definition file.
-- This module contains the definition of the tzpuFusionX project plus enhancements
-- for the MZ-80A.
--
-- Credits:
-- Copyright: (c) 2018-22 Philip Smart <philip.smart@net2net.org>
--
-- History: Nov 2022 - Initial write for the MZ-2000, adaption to MZ-80A underway.
--
---------------------------------------------------------------------------------------------------------
-- 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->.
---------------------------------------------------------------------------------------------------------
library ieee;
library pkgs;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use work.tzpuFusionX_pkg.all;
entity cpld512 is
generic (
SPI_CLK_POLARITY : std_logic := '0'
);
port (
-- Z80 Address Bus
Z80_ADDR : inout std_logic_vector(15 downto 0);
-- Z80 Data Bus
Z80_DATA : inout std_logic_vector(7 downto 0);
-- Z80 Control signals.
Z80_BUSRQn : in std_logic;
Z80_BUSAKn : out std_logic;
Z80_INTn : in std_logic;
Z80_IORQn : inout std_logic;
Z80_MREQn : inout std_logic;
Z80_NMIn : in std_logic;
Z80_RDn : inout std_logic;
Z80_WRn : inout std_logic;
Z80_RESETn : in std_logic; -- Host CPU Reset signal, also CPLD reset.
Z80_HALTn : out std_logic;
Z80_WAITn : in std_logic;
Z80_M1n : inout std_logic;
Z80_RFSHn : inout std_logic;
-- SOM Control Signals
VSOM_SPI_CLK : in std_logic; -- SOM SPI Channel 0 Clock.
VSOM_SPI_MOSI : in std_logic; -- MOSI Input.
VSOM_SPI_MISO : out std_logic; -- MISO Output.
VSOM_SPI_CSn : in std_logic; -- Enable.
-- SOM Parallel Bus.
VSOM_DATA_OUT : out std_logic_vector(7 downto 0); -- Address/Data bus for CPLD control registers.
VSOM_HBYTE : in std_logic; -- Parallel Bus High (1)/Low (0) byte.
VSOM_READY : out std_logic; -- FSM Ready (1), Busy (0)
VSOM_LTSTATE : out std_logic; -- Last T-State in current cycle, 1 = active.
VSOM_BUSRQ : out std_logic; -- Host device requesting Z80 Bus.
VSOM_BUSACK : out std_logic; -- Host device granted Z80 Bus
VSOM_INT : out std_logic; -- Z80 INT signal
VSOM_NMI : out std_logic; -- Z80 NMI signal
VSOM_WAIT : out std_logic; -- Z80 WAIT signal
VSOM_RESET : out std_logic; -- Z80 RESET signal
VSOM_RSV : out std_logic_vector(1 downto 1); -- Reserved pins.
-- SOM Control Signals
PM_RESET : out std_logic; -- Reset SOM
-- VGA_Palette Control
VGA_R : in std_logic_vector(9 downto 7); -- Signals used for detecting blank or no video output.
VGA_G : in std_logic_vector(9 downto 7);
VGA_B : in std_logic_vector(9 downto 8);
-- VGA Control Signals
VGA_PXL_CLK : in std_logic; -- VGA Pixel clock for DAC conversion.
VGA_DISPEN : in std_logic; -- Displayed Enabled (SOM video output).
VGA_VSYNCn : in std_logic; -- SOM VSync.
VGA_HSYNCn : in std_logic; -- SOM HSync.
VGA_COLR : out std_logic; -- COLR colour carrier frequency.
VGA_CSYNCn : out std_logic; -- VGA Composite Sync.
VGA_BLANKn : out std_logic; -- VGA Blank detected.
-- CRT Control Signals
MONO_PXL_CLK : out std_logic; -- Mono CRT pixel clock for DAC conversion.
MONO_BLANKn : out std_logic; -- Mono CRT Blank (no active pixel) detection.
MONO_CSYNCn : out std_logic; -- Mono CRT composite sync.
MONO_RSV : out std_logic;
-- CRT Lower Chrominance Control
MONO_R : out std_logic_vector(2 downto 0); -- Signals to fine tune Red level of monochrome chrominance.
MONO_G : out std_logic_vector(2 downto 0); -- Signals to fine tune Green level of monochrome chrominance.
MONO_B : out std_logic_vector(2 downto 1); -- Signals to fine tune Blue level of monochrome chrominance.
-- MUX Control Signals
VIDEO_SRC : out std_logic; -- Select video source, Mainboard or SOM.
MONO_VIDEO_SRC : out std_logic; -- Select crt video source, Mainboard or SOM.
AUDIO_SRC_L : out std_logic; -- Select Audio Source Left Channel, Mainboard or SOM.
AUDIO_SRC_R : out std_logic; -- Select Audio Source Right Channel, Mainboard or SOM.
-- Mainboard Reset Signals
MB_RESETn : in std_logic; -- Motherboard Reset pressed.
MB_IPLn : in std_logic; -- Motherboard IPL pressed.
-- USB Power Control
VBUS_EN : out std_logic; -- USB Enable Power Output
-- Clocks.
Z80_CLK : in std_logic; -- Host CPU Clock
CLK_50M : in std_logic -- 50MHz oscillator.
);
end entity;
architecture rtl of cpld512 is
-- Finite State Machine states.
type SOMFSMState is
(
IdleCycle,
FetchCycle,
FetchCycle_11,
FetchCycle_20,
FetchCycle_21,
FetchCycle_30,
RefreshCycle,
RefreshCycle_11,
RefreshCycle_20,
RefreshCycle_21,
RefreshCycle_3,
WriteCycle,
WriteCycle_11,
WriteCycle_20,
WriteCycle_21,
WriteCycle_30,
WriteCycle_31,
ReadCycle,
ReadCycle_11,
ReadCycle_20,
ReadCycle_21,
ReadCycle_30,
ReadCycle_31,
WriteIOCycle,
WriteIOCycle_11,
WriteIOCycle_20,
WriteIOCycle_21,
WriteIOCycle_30,
WriteIOCycle_31,
WriteIOCycle_40,
WriteIOCycle_41,
ReadIOCycle,
ReadIOCycle_11,
ReadIOCycle_20,
ReadIOCycle_21,
ReadIOCycle_30,
ReadIOCycle_31,
ReadIOCycle_40,
ReadIOCycle_41,
HaltCycle,
BusReqCycle
);
-- CPU Interface internal signals.
signal Z80_BUSRQni : std_logic;
signal Z80_INTni : std_logic;
signal Z80_IORQni : std_logic;
signal Z80_MREQni : std_logic;
signal Z80_NMIni : std_logic;
signal Z80_RDni : std_logic;
signal Z80_WRni : std_logic;
signal Z80_HALTni : std_logic;
signal Z80_M1ni : std_logic;
signal Z80_RFSHni : std_logic;
signal Z80_DATAi : std_logic_vector(7 downto 0);
signal Z80_BUSRQ_ACKni : std_logic;
-- Internal CPU state control.
signal CPU_ADDR : std_logic_vector(15 downto 0) := (others => '0');
signal CPU_DATA_IN : std_logic_vector(7 downto 0) := (others => '0');
signal CPU_DATA_OUT : std_logic_vector(7 downto 0) := (others => '0');
signal CPU_DATA_EN : std_logic;
-- Clocks.
signal CLK_25Mi : std_logic := '0';
-- Reset control
signal PM_RESETi : std_logic := '1';
signal VSOM_RESETni : std_logic := '1';
-- Refresh control.
signal FSM_STATE : SOMFSMState := IdleCycle;
signal NEW_SPI_CMD : std_logic := '0';
signal VCPU_CS_EDGE : std_logic_vector(1 downto 0) := "11";
signal AUTOREFRESH_CNT : integer range 0 to 7;
signal FSM_STATUS : std_logic := '0';
signal FSM_CHECK_WAIT : std_logic := '0';
signal FSM_WAIT_ACTIVE : std_logic := '0';
signal RFSH_STATUS : std_logic := '0';
signal REFRESH_ADDR : std_logic_vector(7 downto 0);
signal IPAR : std_logic_vector(7 downto 0);
signal AUTOREFRESH : std_logic;
-- Clock edge detection and flagging.
signal Z80_CLKi : std_logic;
signal Z80_CLK_LAST : std_logic_vector(1 downto 0);
signal Z80_CLK_RE : std_logic;
signal Z80_CLK_FE : std_logic;
signal Z80_CLK_TGL : std_logic;
signal CPU_T_STATE_SET : integer range 0 to 5;
signal CPU_LAST_T_STATE : std_logic := '0';
-- SPI Slave interface.
signal SPI_SHIFT_EN : std_logic;
signal SPI_TX_SREG : std_logic_vector(6 downto 0); -- TX Shift Register
signal SPI_RX_SREG : std_logic_vector(7 downto 0); -- RX Shift Register
signal SPI_TX_DATA : std_logic_vector(31 downto 0); -- Data to transmit.
signal SPI_RX_DATA : std_logic_vector(31 downto 0); -- Data received.
signal SPI_BIT_CNT : integer range 0 to 16; -- Count of bits tx/rx'd.
signal SPI_FRAME_CNT : integer range 0 to 4; -- Number of frames received (8bit chunks).
-- SPI Command interface.
signal SOM_CMD : std_logic_vector(7 downto 0) := (others => '0');
signal SPI_NEW_DATA : std_logic;
signal SPI_PROCESSING : std_logic;
signal SPI_CPU_ADDR : std_logic_vector(15 downto 0) := (others => '0');
signal SPI_CPU_DATA : std_logic_vector(7 downto 0) := (others => '0');
-- Test modes.
signal SPI_LOOPBACK_TEST : std_logic := '0';
-- Video/Audio control
signal VIDEO_SRCi : std_logic := '0';
signal MONO_VIDEO_SRCi : std_logic := '0';
signal AUDIO_SRC_Li : std_logic := '0';
signal AUDIO_SRC_Ri : std_logic := '0';
signal VBUS_ENi : std_logic := '1';
function to_std_logic(L: boolean) return std_logic is
begin
if L then
return('1');
else
return('0');
end if;
end function to_std_logic;
begin
-- System RESET.
--
-- Multiple reset sources, Z80_RESETn, MB_IPLn, MB_RESETn. On the MZ-80A, MB_RESETn is a full reset to the power on state.
-- Like the MZ-700, we trigger on Z80_RESETn after having sampled the MB_RESETn state to decide on any extra actions needed within
-- the CPLD and the signals are forwarded onto the SOM so it too can take the correct reset path.
--
-- If the external reset switch is pressed, a Z80_RESETn is invoked sending the signal low for approx 30ms.
-- On the first edge the VSOM_RESETn signal is set which allows the SOM to see it and the Z80 application to enter a reset state.
-- On the second edge, if occurring within 1 second of the first, the PM_RESET signal to the SOM is triggered, held low for 1 second,
-- forcing the SOM to reboot.
SYSRESET: process( Z80_CLKi, Z80_RESETn )
variable timer1 : integer range 0 to 354000 := 0;
variable timer100 : integer range 0 to 10 := 0;
variable timerPMReset : integer range 0 to 10 := 0;
variable resetCount : integer range 0 to 3 := 0;
variable cpuResetEdge : std_logic := '1';
begin
-- Synchronous on the HOST Clock.
if(rising_edge(Z80_CLKi)) then
-- If the PM Reset timer is active, count down and on expiry release the SOM PM_RESET line.
if(timerPMReset = 0 and PM_RESETi = '1') then
PM_RESETi <= '0';
end if;
-- If the VSOM_RESETni is active after reset timer expiry, cancel the RESET state.
if(timerPMReset = 0 and VSOM_RESETni = '0') then
VSOM_RESETni <= '1';
end if;
-- Each time the reset button is pressed, count the edges.
if(Z80_RESETn = '0' and cpuResetEdge = '1' and (resetCount = 0 or timer100 > 5)) then
resetCount := resetCount + 1;
VSOM_RESETni <= '0';
timerPMReset := 5;
timer100 := 0;
-- If there are 2 or more reset signals in a given period it means a SOM reset is required.
if(resetCount >= 2) then
PM_RESETi <= '1';
timerPMReset := 10;
resetCount := 0;
end if;
end if;
-- 100ms interval.
if(timer1 = 354000) then
timer100 := timer100 + 1;
if(timer100 >= 10) then
timer100 := 0;
resetCount := 0;
end if;
if(timerPMReset > 0) then
timerPMReset := timerPMReset - 1;
end if;
end if;
timer1 := timer1 - 1;
cpuResetEdge := Z80_RESETn;
end if;
end process;
-- Create Mono DAC Clock based on primary clock.
MONOCLK: process( CLK_50M )
begin
if(rising_edge(CLK_50M)) then
CLK_25Mi <= not CLK_25Mi;
end if;
end process;
-- SPI Slave input. Receive command and data from the SOM.
SPI_INPUT : process(VSOM_SPI_CLK)
begin
-- SPI_CLK_POLARITY='0' => falling edge; SPI_CLK_POLARITY='1' => rising edge
if(VSOM_SPI_CLK'event and VSOM_SPI_CLK = SPI_CLK_POLARITY) then
if(VSOM_SPI_CSn = '0') then
SPI_RX_SREG <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
-- End of frame then store the data prior to next bit arrival.
-- Convert to Little Endian, same as SOM.
if(SPI_SHIFT_EN = '1' and SPI_FRAME_CNT = 1 and SPI_BIT_CNT = 0) then
SPI_RX_DATA(7 downto 0) <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
elsif(SPI_SHIFT_EN = '1' and SPI_FRAME_CNT = 2 and SPI_BIT_CNT = 0) then
SPI_RX_DATA(15 downto 8) <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
elsif(SPI_SHIFT_EN = '1' and SPI_FRAME_CNT = 3 and SPI_BIT_CNT = 0) then
SPI_RX_DATA(23 downto 16) <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
elsif(SPI_SHIFT_EN = '1' and SPI_FRAME_CNT = 4 and SPI_BIT_CNT = 0) then
SPI_RX_DATA(31 downto 24) <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
end if;
end if;
end if;
end process;
-- SPI Slave output. Return the current data set as selected by the input signals XACT.
SPI_OUTPUT : process(VSOM_SPI_CLK,VSOM_SPI_CSn,SPI_TX_DATA)
begin
if(VSOM_SPI_CSn = '1') then
SPI_SHIFT_EN <= '0';
SPI_BIT_CNT <= 15;
-- SPI_CLK_POLARITY='0' => falling edge; SPI_CLK_POLARITY='1' => risinge edge
elsif(VSOM_SPI_CLK'event and VSOM_SPI_CLK = not SPI_CLK_POLARITY) then
SPI_SHIFT_EN <= '1';
if(SPI_BIT_CNT > 0) then
SPI_BIT_CNT <= SPI_BIT_CNT - 1;
end if;
VSOM_SPI_MISO <= SPI_TX_SREG(6);
SPI_TX_SREG <= SPI_TX_SREG(5 downto 0) & '0';
-- First clock after CS goes active, load up the data to be sent to the SOM.
if(SPI_SHIFT_EN = '0' or SPI_BIT_CNT = 0) then
if(SPI_LOOPBACK_TEST = '1') then
VSOM_SPI_MISO<= SPI_RX_SREG(7);
SPI_TX_SREG <= SPI_RX_SREG(6 downto 0);
elsif(SPI_SHIFT_EN = '0') then
SPI_FRAME_CNT<= 1;
VSOM_SPI_MISO<= SPI_TX_DATA(7);
SPI_TX_SREG <= SPI_TX_DATA(6 downto 0);
elsif(SPI_FRAME_CNT = 1) then
SPI_FRAME_CNT<= 2;
VSOM_SPI_MISO<= SPI_TX_DATA(15);
SPI_TX_SREG <= SPI_TX_DATA(14 downto 8);
elsif(SPI_FRAME_CNT = 2) then
SPI_FRAME_CNT<= 3;
VSOM_SPI_MISO<= SPI_TX_DATA(23);
SPI_TX_SREG <= SPI_TX_DATA(22 downto 16);
else
-- Increment frame count for each word received. We handle 8bit (1 frame), 16bit (2 frames) or 32bit (4 frames) reception.
SPI_FRAME_CNT<= 4;
VSOM_SPI_MISO<= SPI_TX_DATA(31);
SPI_TX_SREG <= SPI_TX_DATA(30 downto 24);
end if;
SPI_BIT_CNT <= 7;
end if;
end if;
end process;
SPI_REGISTER : process(Z80_RESETn, VSOM_SPI_CSn, SPI_FRAME_CNT)
begin
if(Z80_RESETn = '0') then
VIDEO_SRCi <= '0';
VGA_BLANKn <= '1';
VBUS_ENi <= '1';
MONO_VIDEO_SRCi <= '1';
AUDIO_SRC_Li <= '0';
AUDIO_SRC_Ri <= '0';
AUTOREFRESH <= '0';
SPI_LOOPBACK_TEST <= '0';
SOM_CMD <= (others => '0');
SPI_CPU_ADDR <= (others => '0');
SPI_NEW_DATA <= '0';
-- On rising edge of SPI CSn a new data packet from the SOM has arrived and in the shift register SPI_RX_SREG.
-- The variable SPI_FRAME_CNT indicates which byte (frame) in a 32bit word has been transmitted. This allows
-- for 8bit, 16bit and 32bit transmissions.
-- The packet is formatted as follows:
--
-- < SPI_FRAME_CNT=4 >< SPI_FRAME=3 > < SPI_FRAME_CNT=2 >< SPI_FRAME_CNT=1>
-- < 16bit Z80 Address > < Z80 Data ><Command=00..80>
-- 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
--
-- < > < Data ><Command=F0..FF>
-- 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
--
elsif(VSOM_SPI_CSn'event and VSOM_SPI_CSn = '1') then
-- Command is always located in the upper byte of frame 1.
SOM_CMD <= SPI_RX_DATA(7 downto 0);
-- Toggle flag to indicate new data arrived.
SPI_NEW_DATA <= not SPI_NEW_DATA;
-- Process the command. Some commands require the FSM, others can be serviced immediately.
case SPI_RX_DATA(7 downto 0) is
-- Z80XACT(0..15): Setup data and address as provided then execute FSM.
when X"10" | X"11" | X"12" | X"13" | X"14" | X"15" | X"16" | X"17" | -- Fetch
X"18" | X"19" | X"1A" | X"1B" | X"1C" | X"1D" | X"1E" | X"1F" | -- Write
X"20" | X"21" | X"22" | X"23" | X"24" | X"25" | X"26" | X"27" | -- Read
X"28" | X"29" | X"2A" | X"2B" | X"2C" | X"2D" | X"2E" | X"2F" | -- WriteIO
X"30" | X"31" | X"32" | X"33" | X"34" | X"35" | X"36" | X"37" | -- ReadIO
X"38" | X"39" | X"3A" | X"3B" | X"3C" | X"3D" | X"3E" | X"3F" | --
X"40" | X"41" | X"42" | X"43" | X"44" | X"45" | X"46" | X"47" | --
X"48" | X"49" | X"4A" | X"4B" | X"4C" | X"4D" | X"4E" | X"4F" =>
-- Direct address set.
if(SPI_FRAME_CNT = 4) then
SPI_CPU_ADDR <= SPI_RX_DATA(31 downto 16);
else
-- if(SPI_CPU_ADDR >= X"D010" and SPI_CPU_ADDR < X"D020") then
-- SPI_CPU_ADDR <= std_logic_vector(X"D020" + unsigned(SPI_RX_DATA(2 downto 0)));
-- else
SPI_CPU_ADDR <= std_logic_vector(unsigned(SPI_CPU_ADDR) + unsigned(SPI_RX_DATA(2 downto 0)));
-- end if;
end if;
if(SPI_FRAME_CNT > 1) then
SPI_CPU_DATA <= SPI_RX_DATA(15 downto 8);
end if;
-- SETSIGSET1: Set control lines directly.
when X"F0" =>
VIDEO_SRCi <= SPI_RX_DATA(8);
MONO_VIDEO_SRCi <= SPI_RX_DATA(9);
AUDIO_SRC_Li <= SPI_RX_DATA(10);
AUDIO_SRC_Ri <= SPI_RX_DATA(11);
VBUS_ENi <= SPI_RX_DATA(12);
VGA_BLANKn <= not SPI_RX_DATA(13);
-- Enable auto refresh DRAM cycle.
when X"F1" =>
AUTOREFRESH <= '1';
-- Disable auto refresh DRAM cycle.
when X"F2" =>
AUTOREFRESH <= '0';
-- SETLOOPBACK: Enable loopback test mode.
when X"FE" =>
SPI_LOOPBACK_TEST<= '1';
-- No action, called to retrieve status.
when X"00" | X"FF" =>
when others =>
end case;
end if;
end process;
-- Process to detect the Z80 Clock edges. Each edge is used to recreate the Z80 external signals.
--
Z80CLK: process( CLK_50M, Z80_CLKi, Z80_RESETn )
begin
if(Z80_RESETn = '0') then
Z80_CLK_RE <= '1';
Z80_CLK_FE <= '1';
Z80_CLK_TGL <= '1';
elsif(rising_edge(CLK_50M)) then
-- Default is to clear the signals, only active for 1 clock period.
Z80_CLK_RE <= '0';
Z80_CLK_FE <= '0';
Z80_CLK_TGL <= '0';
-- Rising Edge.
if(Z80_CLKi = '1' and Z80_CLK_LAST = "00") then
Z80_CLK_RE <= '1';
-- Toggle on rising edge is delayed by one clock to allow time for command to be decoded.
elsif(Z80_CLKi = '1' and Z80_CLK_LAST = "01") then
Z80_CLK_TGL <= '1';
-- Falling Edge.
elsif(Z80_CLKi = '0' and Z80_CLK_LAST = "11") then
Z80_CLK_FE <= '1';
Z80_CLK_TGL <= '1';
end if;
Z80_CLK_LAST <= Z80_CLK_LAST(0) & Z80_CLKi;
end if;
end process;
-- SOM Finite State Machine.
--
-- A command processor, based on an FSM concept, to process requested commands, ie. Z80 Write, Z80 Read etc.
-- The external signal SOM_CMD_EN, when set, indicates a new command available in SOM_CMD.
--
SOMFSM: process( CLK_50M, Z80_CLKi, Z80_RESETn )
begin
if(Z80_RESETn = '0') then
Z80_IORQni <= '1';
Z80_MREQni <= '1';
Z80_RDni <= '1';
Z80_WRni <= '1';
Z80_HALTni <= '1';
Z80_M1ni <= '1';
Z80_RFSHni <= '1';
Z80_BUSRQ_ACKni <= '1';
FSM_CHECK_WAIT <= '0';
FSM_WAIT_ACTIVE <= '0';
FSM_STATUS <= '0';
FSM_STATE <= IdleCycle;
RFSH_STATUS <= '0';
CPU_DATA_EN <= '0';
CPU_DATA_IN <= (others => '0');
REFRESH_ADDR <= (others => '0');
AUTOREFRESH_CNT <= 7;
IPAR <= (others => '0');
NEW_SPI_CMD <= '0';
VCPU_CS_EDGE <= "11";
SPI_PROCESSING <= '0';
elsif(rising_edge(CLK_50M)) then
-- Bus request mechanism. If an externel Bus Request comes in and the FSM is idle, run the Bus Request command which
-- suspends processing and tri-states the bus.
if(Z80_BUSRQn = '0' and Z80_BUSRQ_ACKni = '1' and FSM_STATE = IdleCycle) then
FSM_STATE <= BusReqCycle;
end if;
if(Z80_BUSRQn = '1' and Z80_BUSRQ_ACKni = '0' and FSM_STATE = IdleCycle) then
Z80_BUSRQ_ACKni <= '1';
end if;
-- New command, set flag as the signal is only 1 clock wide.
if(SPI_LOOPBACK_TEST = '0' and VSOM_SPI_CSn = '1' and VCPU_CS_EDGE = "01") then
NEW_SPI_CMD <= '1';
end if;
-- Whenever we return to Idle or just prior to Refresh from a Fetch cycle set all control signals to default.
if(FSM_STATE = IdleCycle or FSM_STATE = RefreshCycle) then
CPU_DATA_EN <= '0';
Z80_MREQni <= '1';
Z80_IORQni <= '1';
Z80_RDni <= '1';
Z80_WRni <= '1';
Z80_M1ni <= '1';
FSM_STATUS <= '0';
Z80_RFSHni <= '1';
-- Auto DRAM refresh cycles. When enabled, every 7 host clock cycles, a 2 cycle refresh period commences.
-- This will be overriden if the SPI receives a new command.
--
if AUTOREFRESH = '1' and FSM_STATE = IdleCycle then
AUTOREFRESH_CNT <= AUTOREFRESH_CNT - 1;
if(AUTOREFRESH_CNT = 0) then
FSM_STATE <= RefreshCycle_3;
end if;
end if;
end if;
-- If new command has been given and the FSM enters idle state, load up new command for processing.
if(NEW_SPI_CMD = '1' and FSM_STATE = IdleCycle and Z80_CLK_RE = '1') then
NEW_SPI_CMD <= '0';
-- Store new address and data for this command.
CPU_ADDR <= SPI_CPU_ADDR;
if(SPI_CPU_DATA /= CPU_DATA_OUT) then
CPU_DATA_OUT <= SPI_CPU_DATA;
end if;
-- Process the SOM command. The SPI_REGISTER executes non FSM commands and stores FSM
-- data prior to this execution block, which fires 1 cycle later on the same control clock.
-- If the command is not for the FSM then the READY mechanism is held for one
-- further cycle before going inactive.
case SOM_CMD is
when X"10" | X"11" | X"12" | X"13" | X"14" | X"15" | X"16" | X"17" =>
-- Initiate a Fetch Cycle.
FSM_STATE <= FetchCycle;
when X"18" | X"19" | X"1A" | X"1B" | X"1C" | X"1D" | X"1E" | X"1F" =>
-- Set the Z80 data bus value and initiate a Write Cycle.
FSM_STATE <= WriteCycle;
when X"20" | X"21" | X"22" | X"23" | X"24" | X"25" | X"26" | X"27" =>
-- Initiate a Read Cycle.
FSM_STATE <= ReadCycle;
when X"28" | X"29" | X"2A" | X"2B" | X"2C" | X"2D" | X"2E" | X"2F" =>
-- Set the Z80 data bus value and initiate an IO Write Cycle.
-- The SOM should set 15:8 to the B register value.
FSM_STATE <= WriteIOCycle;
when X"30" | X"31" | X"32" | X"33" | X"34" | X"35" | X"36" | X"37" =>
-- Initiate a Read IO Cycle.
FSM_STATE <= ReadIOCycle;
when X"50" =>
-- Register a Halt state.
FSM_STATE <= HaltCycle;
when X"51" =>
-- Initiate a refresh cycle.
FSM_STATE <= RefreshCycle_3;
when X"E0" =>
-- Initiate a Halt Cycle.
FSM_STATE <= HaltCycle;
-- Set the Refresh Address register.
when X"E1" =>
REFRESH_ADDR <= CPU_DATA_OUT;
-- Set the Interrupt Page Address Register.
when X"E2" =>
IPAR <= CPU_DATA_OUT;
when others =>
end case;
-- Toggle the processing flag to negate the new data flag. Used to indicate device is busy.
if(SPI_NEW_DATA /= SPI_PROCESSING) then
SPI_PROCESSING <= not SPI_PROCESSING;
end if;
-- FSM Status bit. When processing a command it is set, cleared when idle. Used by SOM to determine command completion.
FSM_STATUS <= '1';
end if;
-- Refresh status bit. Indicates a Refresh cycle is under way.
if FSM_STATE = RefreshCycle or FSM_STATE = RefreshCycle_11 or FSM_STATE = RefreshCycle_20 or FSM_STATE = RefreshCycle_21 or FSM_STATE = RefreshCycle_3 then
RFSH_STATUS <= '1';
else
RFSH_STATUS <= '0';
end if;
-- If we are in a WAIT sampling 1/2 cycle and wait goes active, set the state so we repeat the full clock cycle by winding back 2 places.
if(FSM_CHECK_WAIT = '1' and Z80_WAITn = '0' and Z80_CLK_TGL = '0') then
FSM_WAIT_ACTIVE <= '1';
end if;
-- On each Z80 edge we advance the FSM to recreate the Z80 external signal transactions.
if(Z80_CLK_TGL = '1') then
-- The FSM advances to the next stage on each Z80 edge unless in Idle state.
if(FSM_STATE /= IdleCycle) then
FSM_STATE <= SOMFSMState'val(SOMFSMState'POS(FSM_STATE)+1);
end if;
-- Half cycle expired so we dont check the Z80 wait again.
FSM_CHECK_WAIT <= '0';
FSM_WAIT_ACTIVE <= '0';
-- FSM to implement all the required Z80 cycles.
--
case FSM_STATE is
when IdleCycle =>
CPU_LAST_T_STATE <= '1';
-- FSM_STATE <= IdleCycle;
-----------------------------
-- Z80 Fetch Cycle.
-----------------------------
when FetchCycle =>
Z80_M1ni <= '0';
when FetchCycle_11 =>
Z80_M1ni <= '0';
Z80_MREQni <= '0';
Z80_RDni <= '0';
when FetchCycle_20 =>
FSM_CHECK_WAIT <= '1';
when FetchCycle_21 =>
if(Z80_WAITn = '0' or FSM_WAIT_ACTIVE = '1') then
FSM_STATE <= FetchCycle_20;
end if;
when FetchCycle_30 =>
-- To meet the timing diagrams, just after Rising edge on T3 clear signals. Data wont be available until
-- a short period before the falling edge of T3 (could be an MZ-80A design restriction or the Z80 timing diagrams are a bit out).
FSM_STATE <= RefreshCycle;
-----------------------------
-- Z80 Refresh Cycle.
-----------------------------
when RefreshCycle =>
-- Latch data from mainboard.
CPU_DATA_IN <= Z80_DATA;
FSM_STATUS <= '0';
Z80_RFSHni <= '0';
when RefreshCycle_11 =>
-- Falling edge of T3 activates the MREQ line.
Z80_MREQni <= '0';
when RefreshCycle_20 =>
when RefreshCycle_21 =>
Z80_MREQni <= '1';
REFRESH_ADDR(6 downto 0) <= REFRESH_ADDR(6 downto 0) + 1;
FSM_STATE <= IdleCycle;
when RefreshCycle_3 =>
Z80_RFSHni <= '0';
FSM_STATE <= RefreshCycle_11;
-----------------------------
-- Z80 Write Cycle.
-----------------------------
when WriteCycle =>
when WriteCycle_11 =>
Z80_MREQni <= '0';
CPU_DATA_EN <= '1';
when WriteCycle_20 =>
FSM_CHECK_WAIT <= '1';
when WriteCycle_21 =>
Z80_WRni <= '0';
if(Z80_WAITn = '0' or FSM_WAIT_ACTIVE = '1') then
FSM_STATE <= WriteCycle_20;
end if;
when WriteCycle_30 =>
when WriteCycle_31 =>
FSM_STATUS <= '0';
Z80_MREQni <= '1';
Z80_WRni <= '1';
FSM_STATE <= IdleCycle;
-----------------------------
-- Z80 Read Cycle.
-----------------------------
when ReadCycle =>
when ReadCycle_11 =>
Z80_MREQni <= '0';
Z80_RDni <= '0';
when ReadCycle_20 =>
FSM_CHECK_WAIT <= '1';
when ReadCycle_21 =>
if(Z80_WAITn = '0' or FSM_WAIT_ACTIVE = '1') then
FSM_STATE <= ReadCycle_20;
end if;
when ReadCycle_30 =>
when ReadCycle_31 =>
-- Latch data from mainboard.
CPU_DATA_IN <= Z80_DATA;
FSM_STATUS <= '0';
FSM_STATE <= IdleCycle;
-----------------------------
-- Z80 IO Write Cycle.
-----------------------------
when WriteIOCycle =>
when WriteIOCycle_11 =>
CPU_DATA_EN <= '1';
when WriteIOCycle_20 =>
Z80_IORQni <= '0';
Z80_WRni <= '0';
when WriteIOCycle_21 =>
when WriteIOCycle_30 =>
FSM_CHECK_WAIT <= '1';
when WriteIOCycle_31 =>
if(Z80_WAITn = '0' or FSM_WAIT_ACTIVE = '1') then
FSM_STATE <= WriteIOCycle_20;
end if;
when WriteIOCycle_40 =>
when WriteIOCycle_41 =>
FSM_STATUS <= '0';
Z80_IORQni <= '1';
Z80_WRni <= '1';
FSM_STATE <= IdleCycle;
-----------------------------
-- Z80 IO Read Cycle.
-----------------------------
when ReadIOCycle =>
when ReadIOCycle_11 =>
when ReadIOCycle_20 =>
Z80_IORQni <= '0';
Z80_RDni <= '0';
when ReadIOCycle_21 =>
when ReadIOCycle_30 =>
FSM_CHECK_WAIT <= '1';
when ReadIOCycle_31 =>
if(Z80_WAITn = '0' or FSM_WAIT_ACTIVE = '1') then
FSM_STATE <= ReadIOCycle_20;
end if;
when ReadIOCycle_40 =>
when ReadIOCycle_41 =>
-- Latch data from mainboard.
CPU_DATA_IN <= Z80_DATA;
FSM_STATUS <= '0';
-- IORQ/RD are deactivated at idle giving 1 clock to latch the data in.
FSM_STATE <= IdleCycle;
-----------------------------
-- Halt Request.
-----------------------------
when HaltCycle =>
Z80_HALTni <= '0';
FSM_STATUS <= '0';
FSM_STATE <= IdleCycle;
-----------------------------
-- Z80 Bus Request.
-----------------------------
when BusReqCycle =>
Z80_BUSRQ_ACKni <= '0';
FSM_STATE <= IdleCycle;
when others =>
FSM_STATE <= IdleCycle;
end case;
end if;
VCPU_CS_EDGE <= VCPU_CS_EDGE(0) & VSOM_SPI_CSn;
end if;
end process;
Z80_CLKi <= not Z80_CLK;
-- CPU Interface tri-state control based on acknowledged bus request.
Z80_ADDR <= IPAR & REFRESH_ADDR when Z80_RFSHni = '0'
else
CPU_ADDR when Z80_BUSRQ_ACKni = '1'
else
(others => 'Z');
Z80_DATA <= CPU_DATA_OUT when Z80_BUSRQ_ACKni = '1' and CPU_DATA_EN = '1'
else
(others => 'Z');
-- Z80_DATAi <= Z80_DATA when Z80_RDn = '0'
-- else (others => '1');
Z80_RDn <= Z80_RDni when Z80_BUSRQ_ACKni = '1'
else 'Z';
Z80_WRn <= Z80_WRni when Z80_BUSRQ_ACKni = '1'
else 'Z';
Z80_M1n <= Z80_M1ni when Z80_BUSRQ_ACKni = '1'
else 'Z';
Z80_RFSHn <= Z80_RFSHni when Z80_BUSRQ_ACKni = '1'
else 'Z';
Z80_MREQn <= Z80_MREQni when Z80_BUSRQ_ACKni = '1'
else 'Z';
Z80_IORQn <= Z80_IORQni when Z80_BUSRQ_ACKni = '1'
else 'Z';
Z80_BUSAKn <= Z80_BUSRQ_ACKni;
-- CPU Interface single state output.
Z80_HALTn <= Z80_HALTni;
-- CPU Interface single state input.
Z80_NMIni <= Z80_NMIn;
Z80_INTni <= Z80_INTn;
Z80_BUSRQni <= Z80_BUSRQn;
-- SOM Reset.
PM_RESET <= PM_RESETi;
-- SOM to CPLD Interface.
VSOM_DATA_OUT <= CPU_DATA_IN when VSOM_HBYTE = '1'
else
FSM_STATUS & RFSH_STATUS & Z80_BUSRQ_ACKni & Z80_BUSRQni & Z80_INTni & Z80_NMIni & Z80_WAITn & Z80_RESETn when VSOM_HBYTE = '0'
else
(others => '0');
-- Loopback test, echo what was received.
SPI_TX_DATA <= SPI_RX_DATA when SPI_LOOPBACK_TEST = '1'
else
--CPU_ADDR & SOM_CMD & FSM_STATUS & RFSH_STATUS & std_logic_vector(to_unsigned(SOMFSMState'POS(FSM_STATE), 6));
CPU_ADDR & CPU_DATA_IN & FSM_STATUS & RFSH_STATUS & Z80_BUSRQ_ACKni & Z80_BUSRQni & Z80_INTni & Z80_NMIni & Z80_WAITn & Z80_RESETn;
-- Signal mirrors.
VSOM_READY <= '0' when FSM_STATUS='1' or SPI_NEW_DATA /= SPI_PROCESSING
else '1'; -- FSM Ready (1), Busy (0)
VSOM_LTSTATE <= '1' when CPU_LAST_T_STATE = '1' -- Last T-State in current cycle.
else '0';
VSOM_BUSRQ <= not Z80_BUSRQn; -- Host device requesting Z80 Bus.
VSOM_BUSACK <= not Z80_BUSRQ_ACKni; -- Host device granted Z80 Bus
VSOM_INT <= not Z80_INTn; -- Z80 INT signal
VSOM_NMI <= not Z80_NMIn; -- Z80 NMI signal
VSOM_WAIT <= not Z80_WAITn; -- Z80 WAIT signal
VSOM_RESET <= not VSOM_RESETni; -- Z80 RESET signal
VSOM_RSV <= (others => '0'); -- Reserved pins.
-- Video/Audio control signals.
VIDEO_SRC <= VIDEO_SRCi;
MONO_VIDEO_SRC <= MONO_VIDEO_SRCi;
AUDIO_SRC_L <= AUDIO_SRC_Li;
AUDIO_SRC_R <= AUDIO_SRC_Ri;
-- USB Power Supply enable.
VBUS_EN <= VBUS_ENi;
-- Monochrome output is based on the incoming VGA to give the best chrominance levels.
MONO_R <= VGA_R;
MONO_G <= VGA_G;
MONO_B <= VGA_B;
-- Blanking is active when all colour signals are at 0. The DAC converts values in range 4v .. 5v to adjust chrominance
-- but true off can obly be achieved by bringing the signal value to 0v which is achieved by a Mux activated with this blanking signal.
MONO_BLANKn <= '0' when VGA_R = "000" and VGA_G = "000" and VGA_B = "000"
else '1';
-- Generate composite sync.
VGA_CSYNCn <= VGA_HSYNCn xor not VGA_VSYNCn;
MONO_CSYNCn <= not VGA_HSYNCn xor not VGA_VSYNCn;
-- DAC clocks.
--VGA_PXL_CLK <= CLK_50M;
MONO_PXL_CLK <= VGA_PXL_CLK;
end architecture;

View File

@@ -0,0 +1,222 @@
---------------------------------------------------------------------------------------------------------
--
-- Name: tzpuFusionX_Toplevel.vhd
-- Version: MZ-80A
-- Created: Nov 2022
-- Author(s): Philip Smart
-- Description: tzpuFusionX CPLD Top Level module.
--
-- This module contains the basic pin definition of the CPLD<->logic needed in the
-- project which targets the MZ-80A host.
--
-- Credits:
-- Copyright: (c) 2018-22 Philip Smart <philip.smart@net2net.org>
--
-- History: Nov 2022 - Snapshot taken from the MZ-2000 version of the tzpuFusionX source.
--
---------------------------------------------------------------------------------------------------------
-- 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.
--
-- along with this program. If not, see <http:--www.gnu.org-licenses->.
---------------------------------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.tzpuFusionX_pkg.all;
library altera;
use altera.altera_syn_attributes.all;
entity tzpuFusionX_MZ80A is
port (
-- Z80 Address Bus
Z80_ADDR : inout std_logic_vector(15 downto 0);
-- Z80 Data Bus
Z80_DATA : inout std_logic_vector(7 downto 0);
-- Z80 Control signals.
Z80_BUSRQn : in std_logic;
Z80_BUSAKn : out std_logic;
Z80_INTn : in std_logic;
Z80_IORQn : inout std_logic;
Z80_MREQn : inout std_logic;
Z80_NMIn : in std_logic;
Z80_RDn : inout std_logic;
Z80_WRn : inout std_logic;
Z80_RESETn : in std_logic; -- Host CPU Reset signal, also CPLD reset.
Z80_HALTn : out std_logic;
Z80_WAITn : in std_logic;
Z80_M1n : inout std_logic;
Z80_RFSHn : inout std_logic;
-- SOM SPI
VSOM_SPI_CSn : in std_logic; -- SPI Slave Select
VSOM_SPI_CLK : in std_logic; -- SPI Clock
VSOM_SPI_MOSI : in std_logic; -- SPI Master Output Slave Input
VSOM_SPI_MISO : out std_logic; -- SPI Master Input Slave Output
-- SOM Parallel Bus.
VSOM_DATA_OUT : out std_logic_vector(7 downto 0); -- Address/Data bus for CPLD control registers.
VSOM_HBYTE : in std_logic; -- Parallel Bus High (1)/Low (0) byte.
VSOM_READY : out std_logic; -- FSM Ready (1), Busy (0)
VSOM_LTSTATE : out std_logic; -- Last T-State in current cycle, 1 = active.
VSOM_BUSRQ : out std_logic; -- Host device requesting Z80 Bus.
VSOM_BUSACK : out std_logic; -- Host device granted Z80 Bus
VSOM_INT : out std_logic; -- Z80 INT signal
VSOM_NMI : out std_logic; -- Z80 NMI signal
VSOM_WAIT : out std_logic; -- Z80 WAIT signal
VSOM_RESET : out std_logic; -- Z80 RESET signal
VSOM_RSV : out std_logic_vector(1 downto 1); -- Reserved pins.
-- SOM Control Signals
PM_RESET : out std_logic; -- Reset SOM
-- VGA_Palette Control
VGA_R : in std_logic_vector(9 downto 7); -- Signals used for detecting blank or no video output.
VGA_G : in std_logic_vector(9 downto 7);
VGA_B : in std_logic_vector(9 downto 8);
-- VGA Control Signals
VGA_PXL_CLK : in std_logic; -- VGA Pixel clock for DAC conversion.
VGA_DISPEN : in std_logic; -- Displayed Enabled (SOM video output).
VGA_VSYNCn : in std_logic; -- SOM VSync.
VGA_HSYNCn : in std_logic; -- SOM HSync.
VGA_COLR : out std_logic; -- COLR colour carrier frequency.
VGA_CSYNCn : out std_logic; -- VGA Composite Sync.
VGA_BLANKn : out std_logic; -- VGA Blank detected.
-- CRT Control Signals
MONO_PXL_CLK : out std_logic; -- Mono CRT pixel clock for DAC conversion.
MONO_BLANKn : out std_logic; -- Mono CRT Blank (no active pixel) detection.
MONO_CSYNCn : out std_logic; -- Mono CRT composite sync.
MONO_RSV : out std_logic;
-- CRT Lower Chrominance Control
MONO_R : out std_logic_vector(2 downto 0); -- Signals to fine tune Red level of monochrome chrominance.
MONO_G : out std_logic_vector(2 downto 0); -- Signals to fine tune Green level of monochrome chrominance.
MONO_B : out std_logic_vector(2 downto 1); -- Signals to fine tune Blue level of monochrome chrominance.
-- MUX Control Signals
VIDEO_SRC : out std_logic; -- Select video source, Mainboard or SOM.
MONO_VIDEO_SRC : out std_logic; -- Select crt video source, Mainboard or SOM.
AUDIO_SRC_L : out std_logic; -- Select Audio Source Left Channel, Mainboard or SOM.
AUDIO_SRC_R : out std_logic; -- Select Audio Source Right Channel, Mainboard or SOM.
-- Mainboard Reset Signals
MB_RESETn : in std_logic; -- Motherboard Reset pressed.
MB_IPLn : in std_logic; -- Motherboard IPL pressed.
-- USB Power Control
VBUS_EN : out std_logic; -- USB Enable Power Output
-- Clocks.
Z80_CLK : in std_logic; -- Host CPU Clock
CLK_50M : in std_logic -- 50MHz oscillator.
);
END entity;
architecture rtl of tzpuFusionX_MZ80A is
begin
cpldl512Toplevel : entity work.cpld512
generic map (
SPI_CLK_POLARITY => '0'
)
port map
(
-- Z80 Address Bus
Z80_ADDR => Z80_ADDR,
-- Z80 Data Bus
Z80_DATA => Z80_DATA,
-- Z80 Control signals.
Z80_BUSRQn => Z80_BUSRQn,
Z80_BUSAKn => Z80_BUSAKn,
Z80_INTn => Z80_INTn,
Z80_IORQn => Z80_IORQn,
Z80_MREQn => Z80_MREQn,
Z80_NMIn => Z80_NMIn,
Z80_RDn => Z80_RDn,
Z80_WRn => Z80_WRn,
Z80_RESETn => Z80_RESETn,
Z80_HALTn => Z80_HALTn,
Z80_WAITn => Z80_WAITn,
Z80_M1n => Z80_M1n,
Z80_RFSHn => Z80_RFSHn,
-- SOM SPI
VSOM_SPI_CSn => VSOM_SPI_CSn, -- SPI Slave Select
VSOM_SPI_CLK => VSOM_SPI_CLK, -- SPI Clock
VSOM_SPI_MOSI => VSOM_SPI_MOSI, -- SPI Master Output Slave Input
VSOM_SPI_MISO => VSOM_SPI_MISO, -- SPI Master Input Slave Output
-- SOM Parallel Bus.
VSOM_DATA_OUT => VSOM_DATA_OUT, -- Address/Data bus for CPLD control registers.
VSOM_HBYTE => VSOM_HBYTE, -- Parallel Bus High (1)/Low (0) byte.
VSOM_READY => VSOM_READY, -- FSM Ready (1), Busy (0)
VSOM_LTSTATE => VSOM_LTSTATE, -- Last T-State in current cycle.
VSOM_BUSRQ => VSOM_BUSRQ, -- Host device requesting Z80 Bus.
VSOM_BUSACK => VSOM_BUSACK, -- Host device granted Z80 Bus
VSOM_INT => VSOM_INT, -- Z80 INT signal
VSOM_NMI => VSOM_NMI, -- Z80 NMI signal
VSOM_WAIT => VSOM_WAIT, -- Z80 WAIT signal
VSOM_RESET => VSOM_RESET, -- Z80 RESET signal
VSOM_RSV => VSOM_RSV, -- Reserved pins.
-- SOM Control Signals
PM_RESET => PM_RESET, -- Reset SOM
-- VGA_Palette Control
VGA_R => VGA_R, -- Signals used for detecting blank or no video output.
VGA_G => VGA_G,
VGA_B => VGA_B,
-- VGA Control Signals
VGA_PXL_CLK => VGA_PXL_CLK, -- VGA Pixel clock for DAC conversion.
VGA_DISPEN => VGA_DISPEN, -- Displayed Enabled (SOM video output).
VGA_VSYNCn => VGA_VSYNCn, -- SOM VSync.
VGA_HSYNCn => VGA_HSYNCn, -- SOM HSync.
VGA_COLR => VGA_COLR, -- COLR colour carrier frequency.
VGA_CSYNCn => VGA_CSYNCn, -- VGA Composite Sync.
VGA_BLANKn => VGA_BLANKn, -- VGA Blank detected.
-- CRT Control Signals
MONO_PXL_CLK => MONO_PXL_CLK, -- Mono CRT pixel clock for DAC conversion.
MONO_BLANKn => MONO_BLANKn, -- Mono CRT Blank (no active pixel) detection.
MONO_CSYNCn => MONO_CSYNCn, -- Mono CRT composite sync.
MONO_RSV => MONO_RSV,
-- CRT Lower Chrominance Control
MONO_R => MONO_R, -- Signals to fine tune Red level of monochrome chrominance.
MONO_G => MONO_G, -- Signals to fine tune Green level of monochrome chrominance.
MONO_B => MONO_B, -- Signals to fine tune Blue level of monochrome chrominance.
-- MUX Control Signals
VIDEO_SRC => VIDEO_SRC, -- Select video source, Mainboard or SOM.
MONO_VIDEO_SRC => MONO_VIDEO_SRC, -- Select crt video source, Mainboard or SOM.
AUDIO_SRC_L => AUDIO_SRC_L, -- Select Audio Source Left Channel, Mainboard or SOM.
AUDIO_SRC_R => AUDIO_SRC_R, -- Select Audio Source Right Channel, Mainboard or SOM.
-- Mainboard Reset Signals=> MONO_R,
MB_RESETn => MB_RESETn, -- Motherboard Reset pressed.
MB_IPLn => MB_IPLn, -- Motherboard IPL pressed.
-- USB Power Control
VBUS_EN => VBUS_EN, -- USB Enable Power Output
-- Clocks.
Z80_CLK => Z80_CLK, -- Host CPU Clock
CLK_50M => CLK_50M -- 50MHz oscillator.
);
end architecture;

View File

@@ -0,0 +1,221 @@
---------------------------------------------------------------------------------------------------------
--
-- Name: tzpuFusionX_pkg.vhd
-- Created: Nov 2022
-- Author(s): Philip Smart
-- Description: tzpuFusionX CPLD configuration file.
--
-- This module contains parameters for the CPLD in the tzpuFusionX project
-- which targets the MZ-80A host.
--
-- Credits:
-- Copyright: (c) 2018-22 Philip Smart <philip.smart@net2net.org>
--
-- History: Nov 2022 - Snapshot taken from the MZ-2000 version of the tzpuFusionX source.
--
---------------------------------------------------------------------------------------------------------
-- 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->.
---------------------------------------------------------------------------------------------------------
library ieee;
library pkgs;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
package tzpuFusionX_pkg is
------------------------------------------------------------
-- Constants
------------------------------------------------------------
-- Potential logic state constants.
constant YES : std_logic := '1';
constant NO : std_logic := '0';
constant HI : std_logic := '1';
constant LO : std_logic := '0';
constant ONE : std_logic := '1';
constant ZERO : std_logic := '0';
constant HIZ : std_logic := 'Z';
-- CPLD Command instructions.
constant CPLD_CMD_RESET_HOST : integer := 1;
constant CPLD_CMD_HOLD_HOST_BUS : integer := 2;
constant CPLD_CMD_RELEASE_HOST_BUS: integer := 3;
-- Target hardware modes.
constant MODE_MZ80K : integer := 0;
constant MODE_MZ80C : integer := 1;
constant MODE_MZ1200 : integer := 2;
constant MODE_MZ80A : integer := 3;
constant MODE_MZ700 : integer := 4;
constant MODE_MZ800 : integer := 5;
constant MODE_MZ80B : integer := 6;
constant MODE_MZ2000 : integer := 7;
-- Memory management modes.
constant TZMM_ORIG : integer := 00; -- Original Sharp mode, no tranZPUter features are selected except the I/O control registers (default: 0x60-063).
constant TZMM_BOOT : integer := 01; -- Original mode but E800-EFFF is mapped to tranZPUter RAM so TZFS can be booted.
constant TZMM_TZFS : integer := 02; -- TZFS main memory configuration. all memory is in tranZPUter RAM, E800-FFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected.
constant TZMM_TZFS2 : integer := 03; -- TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 1.
constant TZMM_TZFS3 : integer := 04; -- TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 2.
constant TZMM_TZFS4 : integer := 05; -- TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 3.
constant TZMM_CPM : integer := 06; -- CPM main memory configuration, all memory on the tranZPUter board, 64K block 4 selected. Special case for F3C0:F3FF & F7C0:F7FF (floppy disk paging vectors) which resides on the mainboard.
constant TZMM_CPM2 : integer := 07; -- CPM main memory configuration, F000-FFFF are on the tranZPUter board in block 4, 0040-CFFF and E800-EFFF are in block 5, mainboard for D000-DFFF (video), E000-E800 (Memory control) selected.
-- Special case for 0000:003F (interrupt vectors) which resides in block 4, F3FE:F3FF & F7FE:F7FF (floppy disk paging vectors) which resides on the mainboard.
constant TZMM_COMPAT : integer := 08; -- Compatibility monitor mode, monitor ROM on mainboard, RAM on tranZPUter in Block 0 1000-CFFF.
constant TZMM_HOSTACCESS : integer := 09; -- Monitor ROM 0000-0FFF and Main DRAM 0x1000-0xD000, video and memory mapped I/O are on the host machine, User/Floppy ROM E800-FFFF are in tranZPUter memory.
constant TZMM_MZ700_0 : integer := 10; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the mainboard.
constant TZMM_MZ700_1 : integer := 11; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
constant TZMM_MZ700_2 : integer := 12; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
constant TZMM_MZ700_3 : integer := 13; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
constant TZMM_MZ700_4 : integer := 14; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
constant TZMM_MZ800 : integer := 15; -- MZ800 Mode - Running on MZ800 hardware, configuration set according to MZ700/MZ800 mode.
constant TZMM_MZ2000 : integer := 16; -- MZ2000 Mode - Running on MZ2000 hardware, configuration set according to runtime configuration registers.
constant TZMM_FPGA : integer := 21; -- Open up access for the K64F to the FPGA resources such as memory. All other access to RAM or mainboard is blocked.
constant TZMM_TZPUM : integer := 22; -- Everything in on mainboard, no access to tranZPUter memory.
constant TZMM_TZPU : integer := 23; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
constant TZMM_TZPU0 : integer := 24; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
constant TZMM_TZPU1 : integer := 25; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 1 is selected.
constant TZMM_TZPU2 : integer := 26; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 2 is selected.
constant TZMM_TZPU3 : integer := 27; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 3 is selected.
constant TZMM_TZPU4 : integer := 28; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 4 is selected.
constant TZMM_TZPU5 : integer := 29; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 5 is selected.
constant TZMM_TZPU6 : integer := 30; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 6 is selected.
constant TZMM_TZPU7 : integer := 31; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 7 is selected.
------------------------------------------------------------
-- Configurable parameters.
------------------------------------------------------------
-- Target hardware.
constant CPLD_HOST_HW : integer := MODE_MZ700;
-- Target video hardware.
constant CPLD_HAS_FPGA_VIDEO : std_logic := '1';
-- Version of hdl.
constant CPLD_VERSION : integer := 2;
-- Clock source for the secondary clock. If a K64F is installed then enable it otherwise use the onboard oscillator.
--
constant USE_K64F_CTL_CLOCK : integer := 1;
------------------------------------------------------------
-- Function prototypes
------------------------------------------------------------
-- Find the maximum of two integers.
function IntMax(a : in integer; b : in integer) return integer;
-- Find the number of bits required to represent an integer.
function log2ceil(arg : positive) return natural;
-- Function to calculate the number of whole 'clock' cycles in a given time period, the period being in ns.
function clockTicks(period : in integer; clock : in integer) return integer;
-- Function to reverse the order of the bits in a standard logic vector.
-- ie. 1010 becomes 0101
function reverse_vector(slv:std_logic_vector) return std_logic_vector;
-- Function to convert an integer (0 or 1) into std_logic.
--
function to_std_logic(i : in integer) return std_logic;
-- Function to return the value of a bit as an integer for array indexing etc.
function bit_to_integer( s : std_logic ) return natural;
------------------------------------------------------------
-- Records
------------------------------------------------------------
------------------------------------------------------------
-- Components
------------------------------------------------------------
end tzpuFusionX_pkg;
------------------------------------------------------------
-- Function definitions.
------------------------------------------------------------
package body tzpuFusionX_pkg is
-- Find the maximum of two integers.
function IntMax(a : in integer; b : in integer) return integer is
begin
if a > b then
return a;
else
return b;
end if;
return a;
end function IntMax;
-- Find the number of bits required to represent an integer.
function log2ceil(arg : positive) return natural is
variable tmp : positive := 1;
variable log : natural := 0;
begin
if arg = 1 then
return 0;
end if;
while arg > tmp loop
tmp := tmp * 2;
log := log + 1;
end loop;
return log;
end function;
-- Function to calculate the number of whole 'clock' cycles in a given time period, the period being in ns.
function clockTicks(period : in integer; clock : in integer) return integer is
variable ticks : real;
variable fracTicks : real;
begin
ticks := (Real(period) * Real(clock)) / 1000000000.0;
fracTicks := ticks - CEIL(ticks);
if fracTicks > 0.0001 then
return Integer(CEIL(ticks + 1.0));
else
return Integer(CEIL(ticks));
end if;
end function;
function reverse_vector(slv:std_logic_vector) return std_logic_vector is
variable target : std_logic_vector(slv'high downto slv'low);
begin
for idx in slv'high downto slv'low loop
target(idx) := slv(slv'low + (slv'high-idx));
end loop;
return target;
end reverse_vector;
function to_std_logic(i : in integer) return std_logic is
begin
if i = 0 then
return '0';
end if;
return '1';
end function;
-- Function to return the value of a bit as an integer for array indexing etc.
function bit_to_integer( s : std_logic ) return natural is
begin
if s = '1' then
return 1;
else
return 0;
end if;
end function;
end package body;