Revision 115
Added by markw about 11 years ago
chameleon/atari800core.cdf | ||
---|---|---|
/* Quartus II 64-Bit Version 12.1 Build 243 01/31/2013 Service Pack 1.33 SJ Web Edition */
|
||
JedecChain;
|
||
FileRevision(JESD32A);
|
||
DefaultMfr(6E);
|
||
|
||
P ActionCode(Ign)
|
||
Device PartName(CPLD) MfrSpec(OpMask(0));
|
||
P ActionCode(Cfg)
|
||
Device PartName(EP3C25E144) Path("C:/Users/Mark/Desktop/FPGA/build/output_files/") File("atari800core.sof") MfrSpec(OpMask(1));
|
||
|
||
ChainEnd;
|
||
|
||
AlteraBegin;
|
||
ChainType(JTAG);
|
||
AlteraEnd;
|
chameleon/atari800core.qsf | ||
---|---|---|
# -------------------------------------------------------------------------- #
|
||
#
|
||
# 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 32-bit
|
||
# Version 13.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition
|
||
# Date created = 12:05:10 July 13, 2014
|
||
#
|
||
# -------------------------------------------------------------------------- #
|
||
#
|
||
# Notes:
|
||
#
|
||
# 1) The default values for assignments are stored in the file:
|
||
# atari800core_assignment_defaults.qdf
|
||
# If this file doesn't exist, see file:
|
||
# assignment_defaults.qdf
|
||
#
|
||
# 2) Altera recommends that you do not modify this file. This
|
||
# file is updated automatically by the Quartus II software
|
||
# and any changes you make may be lost or overwritten.
|
||
#
|
||
# -------------------------------------------------------------------------- #
|
||
|
||
|
||
set_global_assignment -name FAMILY "Cyclone III"
|
||
set_global_assignment -name DEVICE EP3C25E144C8
|
||
set_global_assignment -name TOP_LEVEL_ENTITY atari800core_chameleon
|
||
set_global_assignment -name ORIGINAL_QUARTUS_VERSION "13.0 SP1"
|
||
set_global_assignment -name PROJECT_CREATION_TIME_DATE "12:05:10 JULY 13, 2014"
|
||
set_global_assignment -name LAST_QUARTUS_VERSION "12.1 SP1.33"
|
||
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
|
||
set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
|
||
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
|
||
set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144
|
||
set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8
|
||
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1
|
||
set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE SPEED
|
||
set_global_assignment -name NOMINAL_CORE_SUPPLY_VOLTAGE 1.2V
|
||
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
|
||
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||
set_global_assignment -name LL_ROOT_REGION ON -section_id "Root Region"
|
||
set_global_assignment -name LL_MEMBER_STATE LOCKED -section_id "Root Region"
|
||
set_instance_assignment -name MULTICYCLE 2 -from "cpu_6510:my6510|cpu65xx:cpuInstance|*" -to "cpu_6510:my6510|cpu65xx:cpuInstance|*"
|
||
set_location_assignment PIN_111 -to red[0]
|
||
set_location_assignment PIN_110 -to red[1]
|
||
set_location_assignment PIN_106 -to red[2]
|
||
set_location_assignment PIN_105 -to red[3]
|
||
set_location_assignment PIN_104 -to red[4]
|
||
set_location_assignment PIN_103 -to grn[0]
|
||
set_location_assignment PIN_101 -to grn[1]
|
||
set_location_assignment PIN_100 -to grn[2]
|
||
set_location_assignment PIN_99 -to grn[3]
|
||
set_location_assignment PIN_98 -to grn[4]
|
||
set_location_assignment PIN_112 -to blu[0]
|
||
set_location_assignment PIN_133 -to blu[1]
|
||
set_location_assignment PIN_135 -to blu[2]
|
||
set_location_assignment PIN_136 -to blu[3]
|
||
set_location_assignment PIN_137 -to blu[4]
|
||
set_location_assignment PIN_44 -to sd_clk
|
||
set_location_assignment PIN_42 -to sd_addr[12]
|
||
set_location_assignment PIN_33 -to sd_addr[11]
|
||
set_location_assignment PIN_144 -to sd_addr[10]
|
||
set_location_assignment PIN_31 -to sd_addr[9]
|
||
set_location_assignment PIN_28 -to sd_addr[8]
|
||
set_location_assignment PIN_11 -to sd_addr[7]
|
||
set_location_assignment PIN_10 -to sd_addr[6]
|
||
set_location_assignment PIN_8 -to sd_addr[5]
|
||
set_location_assignment PIN_7 -to sd_addr[4]
|
||
set_location_assignment PIN_30 -to sd_addr[3]
|
||
set_location_assignment PIN_32 -to sd_addr[2]
|
||
set_location_assignment PIN_6 -to sd_addr[1]
|
||
set_location_assignment PIN_4 -to sd_addr[0]
|
||
set_location_assignment PIN_39 -to sd_ba_0
|
||
set_location_assignment PIN_143 -to sd_ba_1
|
||
set_location_assignment PIN_50 -to sd_we_n
|
||
set_location_assignment PIN_43 -to sd_ras_n
|
||
set_location_assignment PIN_46 -to sd_cas_n
|
||
set_location_assignment PIN_76 -to sd_data[15]
|
||
set_location_assignment PIN_77 -to sd_data[14]
|
||
set_location_assignment PIN_72 -to sd_data[13]
|
||
set_location_assignment PIN_69 -to sd_data[12]
|
||
set_location_assignment PIN_67 -to sd_data[11]
|
||
set_location_assignment PIN_65 -to sd_data[10]
|
||
set_location_assignment PIN_60 -to sd_data[9]
|
||
set_location_assignment PIN_58 -to sd_data[8]
|
||
set_location_assignment PIN_59 -to sd_data[7]
|
||
set_location_assignment PIN_64 -to sd_data[6]
|
||
set_location_assignment PIN_66 -to sd_data[5]
|
||
set_location_assignment PIN_68 -to sd_data[4]
|
||
set_location_assignment PIN_71 -to sd_data[3]
|
||
set_location_assignment PIN_79 -to sd_data[2]
|
||
set_location_assignment PIN_80 -to sd_data[1]
|
||
set_location_assignment PIN_83 -to sd_data[0]
|
||
set_location_assignment PIN_51 -to sd_ldqm
|
||
set_location_assignment PIN_49 -to sd_udqm
|
||
set_location_assignment PIN_25 -to clk8
|
||
set_location_assignment PIN_142 -to nHSync
|
||
set_location_assignment PIN_141 -to nVSync
|
||
set_location_assignment PIN_87 -to mux_clk
|
||
set_location_assignment PIN_119 -to mux[0]
|
||
set_location_assignment PIN_115 -to mux[1]
|
||
set_location_assignment PIN_114 -to mux[2]
|
||
set_location_assignment PIN_113 -to mux[3]
|
||
set_location_assignment PIN_125 -to mux_d[0]
|
||
set_location_assignment PIN_121 -to mux_d[1]
|
||
set_location_assignment PIN_120 -to mux_d[2]
|
||
set_location_assignment PIN_132 -to mux_d[3]
|
||
set_location_assignment PIN_126 -to mux_q[0]
|
||
set_location_assignment PIN_127 -to mux_q[1]
|
||
set_location_assignment PIN_128 -to mux_q[2]
|
||
set_location_assignment PIN_129 -to mux_q[3]
|
||
set_location_assignment PIN_86 -to sigmaL
|
||
set_location_assignment PIN_85 -to sigmaR
|
||
set_location_assignment PIN_89 -to dotclock_n
|
||
set_location_assignment PIN_88 -to phi2_n
|
||
set_location_assignment PIN_91 -to romlh_n
|
||
set_location_assignment PIN_90 -to ioef_n
|
||
set_location_assignment PIN_13 -to spi_miso
|
||
set_location_assignment PIN_22 -to mmc_cd_n
|
||
set_location_assignment PIN_24 -to mmc_wp
|
||
set_location_assignment PIN_52 -to usart_tx
|
||
set_location_assignment PIN_53 -to usart_clk
|
||
set_location_assignment PIN_54 -to usart_rts
|
||
set_location_assignment PIN_55 -to usart_cts
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[12]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[0]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[11]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[10]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[9]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[8]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[7]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[6]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[5]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[4]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[3]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[2]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_addr[1]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_ba_0
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_ba_1
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_cas_n
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_clk
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_ldqm
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_ras_n
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_udqm
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_we_n
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[15]
|
||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[15]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[14]
|
||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[14]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[13]
|
||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[13]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[12]
|
||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[12]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[11]
|
||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[11]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[10]
|
||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[10]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[9]
|
||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[9]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[8]
|
||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[8]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[7]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[6]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[5]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[4]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[3]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[2]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[1]
|
||
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to sd_data[0]
|
||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[7]
|
||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[6]
|
||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[5]
|
||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[4]
|
||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[3]
|
||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[2]
|
||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[1]
|
||
set_instance_assignment -name FAST_INPUT_REGISTER ON -to sd_data[0]
|
||
set_location_assignment PIN_23 -to freeze_n
|
||
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
|
||
set_global_assignment -name CDF_FILE atari800core.cdf
|
||
set_global_assignment -name VHDL_FILE chameleon_docking_station.vhd
|
||
set_global_assignment -name VHDL_FILE chameleon_1mhz.vhd
|
||
set_global_assignment -name VHDL_FILE chameleon_1khz.vhd
|
||
set_global_assignment -name VHDL_FILE chameleon_led.vhd
|
||
set_global_assignment -name VHDL_FILE chameleon_phi_clock_e.vhd
|
||
set_global_assignment -name VHDL_FILE chameleon_phi_clock_a.vhd
|
||
set_global_assignment -name VHDL_FILE atari800core_chameleon.vhd
|
||
set_global_assignment -name QIP_FILE pll.qip
|
||
set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||
set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||
set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||
set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||
set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||
|
||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||
|
chameleon/atari800core.sdc | ||
---|---|---|
create_clock -period 8MHz [get_ports CLK8]
|
||
derive_pll_clocks
|
||
derive_clock_uncertainty
|
||
|
chameleon/atari800core_chameleon.vhd | ||
---|---|---|
---------------------------------------------------------------------------
|
||
-- (c) 2014 mark watson
|
||
-- I am happy for anyone to use this for non-commercial use.
|
||
-- If my vhdl files are used commercially or otherwise sold,
|
||
-- please contact me for explicit permission at scrameta (gmail).
|
||
-- This applies for source and binary form and derived works.
|
||
---------------------------------------------------------------------------
|
||
|
||
LIBRARY ieee;
|
||
USE ieee.std_logic_1164.all;
|
||
use ieee.numeric_std.all;
|
||
|
||
LIBRARY work;
|
||
|
||
entity atari800core_chameleon is
|
||
port
|
||
(
|
||
-- VGA
|
||
red : OUT STD_LOGIC_VECTOR(4 downto 0);
|
||
grn : OUT STD_LOGIC_VECTOR(4 downto 0);
|
||
blu : OUT STD_LOGIC_VECTOR(4 downto 0);
|
||
nHSync: OUT STD_LOGIC;
|
||
nVSync: OUT STD_LOGIC;
|
||
|
||
-- SDRAM
|
||
sd_clk : OUT STD_LOGIC;
|
||
sd_addr : OUT STD_LOGIC_VECTOR(12 downto 0);
|
||
sd_ba_0 : OUT STD_LOGIC;
|
||
sd_ba_1 : OUT STD_LOGIC;
|
||
sd_we_n : OUT STD_LOGIC;
|
||
sd_ras_n : OUT STD_LOGIC;
|
||
sd_cas_n : OUT STD_LOGIC;
|
||
sd_data :INOUT STD_LOGIC_VECTOR(15 downto 0);
|
||
sd_ldqm : OUT STD_LOGIC;
|
||
sd_udqm : OUT STD_LOGIC;
|
||
|
||
-- Clocks
|
||
clk8 : in std_logic;
|
||
phi2_n : in std_logic;
|
||
dotclock_n : in std_logic;
|
||
|
||
-- Bus
|
||
romlh_n : in std_logic;
|
||
ioef_n : in std_logic;
|
||
|
||
-- Buttons
|
||
freeze_n : in std_logic;
|
||
|
||
-- MMC/SPI
|
||
spi_miso : in std_logic;
|
||
mmc_cd_n : in std_logic;
|
||
mmc_wp : in std_logic;
|
||
-- mosi is on the MUX...
|
||
|
||
-- MUX CPLD
|
||
mux_clk : out std_logic;
|
||
mux : out unsigned(3 downto 0);
|
||
mux_d : out unsigned(3 downto 0);
|
||
mux_q : in unsigned(3 downto 0);
|
||
|
||
-- USART
|
||
usart_tx : in std_logic;
|
||
usart_clk : in std_logic;
|
||
usart_rts : in std_logic;
|
||
usart_cts : in std_logic;
|
||
|
||
-- Audio
|
||
sigmaL : out std_logic;
|
||
sigmaR : out std_logic
|
||
);
|
||
end atari800core_chameleon;
|
||
|
||
architecture vhdl of atari800core_chameleon is
|
||
|
||
component hq_dac
|
||
port (
|
||
reset :in std_logic;
|
||
clk :in std_logic;
|
||
clk_ena : in std_logic;
|
||
pcm_in : in std_logic_vector(19 downto 0);
|
||
dac_out : out std_logic
|
||
);
|
||
end component;
|
||
|
||
signal AUDIO_L_RAW : std_logic_vector(15 downto 0);
|
||
signal AUDIO_R_RAW : std_logic_vector(15 downto 0);
|
||
|
||
signal VGA_VS_RAW : std_logic;
|
||
signal VGA_HS_RAW : std_logic;
|
||
|
||
signal RESET_n : std_logic;
|
||
signal PLL_LOCKED : std_logic;
|
||
signal CLK : std_logic;
|
||
|
||
-- MUX
|
||
signal mux_clk_reg : std_logic := '0';
|
||
signal mux_reg : unsigned(3 downto 0) := (others => '1');
|
||
signal mux_d_reg : unsigned(3 downto 0) := (others => '1');
|
||
|
||
-- LEDs
|
||
signal led_green : std_logic;
|
||
signal led_red : std_logic;
|
||
|
||
-- clocks...
|
||
signal sysclk : std_logic;
|
||
signal ena_1mhz : std_logic;
|
||
signal ena_1khz : std_logic;
|
||
signal phi2 : std_logic;
|
||
signal no_clock : std_logic;
|
||
|
||
-- Docking station
|
||
signal docking_station : std_logic;
|
||
signal docking_ena : std_logic;
|
||
signal docking_irq : std_logic;
|
||
signal irq_n : std_logic;
|
||
|
||
signal docking_joystick1 : unsigned(5 downto 0);
|
||
signal docking_joystick2 : unsigned(5 downto 0);
|
||
signal docking_joystick3 : unsigned(5 downto 0);
|
||
signal docking_joystick4 : unsigned(5 downto 0);
|
||
|
||
-- PS/2 Keyboard
|
||
signal ps2_keyboard_clk_in : std_logic;
|
||
signal ps2_keyboard_dat_in : std_logic;
|
||
--signal ps2_keyboard_clk_out : std_logic;
|
||
--signal ps2_keyboard_dat_out : std_logic;
|
||
|
||
begin
|
||
RESET_N <= PLL_LOCKED;
|
||
|
||
-- disable unused parts
|
||
-- sdram
|
||
sd_clk <= 'Z';
|
||
sd_addr <= (others=>'0');
|
||
sd_ba_0 <= '0';
|
||
sd_ba_1 <= '0';
|
||
sd_we_n <= '1';
|
||
sd_ras_n <= '1';
|
||
sd_cas_n <= '1';
|
||
sd_data <= (others=>'Z');
|
||
sd_ldqm <= '0';
|
||
sd_udqm <= '0';
|
||
|
||
-- simplest possible implementation
|
||
-- pll
|
||
pll : ENTITY work.pll
|
||
PORT MAP
|
||
(
|
||
inclk0 => clk8,
|
||
c0 => clk,
|
||
locked => pll_locked
|
||
);
|
||
|
||
-- core
|
||
atari800core : ENTITY work.atari800core_helloworld
|
||
GENERIC MAP
|
||
(
|
||
cycle_length => 32,
|
||
|
||
video_bits => 5,
|
||
|
||
internal_rom => 1,
|
||
internal_ram => 16384
|
||
)
|
||
PORT MAP
|
||
(
|
||
CLK => clk,
|
||
RESET_N => RESET_N,
|
||
|
||
-- VIDEO OUT - PAL/NTSC, original Atari timings approx (may be higher res)
|
||
VIDEO_VS => vga_vs_raw,
|
||
VIDEO_HS => vga_hs_raw,
|
||
VIDEO_B => blu,
|
||
VIDEO_G => grn,
|
||
VIDEO_R => red,
|
||
|
||
-- AUDIO OUT - Pokey/GTIA 1-bit and Covox all mixed
|
||
AUDIO_L => audio_l_raw,
|
||
AUDIO_R => audio_r_raw,
|
||
|
||
-- JOYSTICK
|
||
JOY1_n => std_logic_vector(docking_joystick1)(4 downto 0),
|
||
JOY2_n => std_logic_vector(docking_joystick2)(4 downto 0),
|
||
|
||
-- KEYBOARD
|
||
PS2_CLK => ps2_keyboard_clk_in,
|
||
PS2_DAT => ps2_keyboard_dat_in,
|
||
|
||
-- video standard
|
||
PAL => '1'
|
||
);
|
||
|
||
-- video glue
|
||
nHSync <= (VGA_HS_RAW xor VGA_VS_RAW);
|
||
nVSync <= (VGA_VS_RAW);
|
||
|
||
-- audio glue
|
||
dac_left : hq_dac
|
||
port map
|
||
(
|
||
reset => not(reset_n),
|
||
clk => clk,
|
||
clk_ena => '1',
|
||
pcm_in => AUDIO_L_RAW&"0000",
|
||
dac_out => sigmaL
|
||
);
|
||
|
||
dac_right : hq_dac
|
||
port map
|
||
(
|
||
reset => not(reset_n),
|
||
clk => clk,
|
||
clk_ena => '1',
|
||
pcm_in => AUDIO_R_RAW&"0000",
|
||
dac_out => sigmaR
|
||
);
|
||
|
||
-- Some common chameleon parts - e.g. mux - taken from the hardware test
|
||
sysclk <= clk;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
-- 1 Mhz and 1 Khz clocks
|
||
-- -----------------------------------------------------------------------
|
||
my1Mhz : entity work.chameleon_1mhz
|
||
generic map (
|
||
--clk_ticks_per_usec => 100
|
||
clk_ticks_per_usec => 57
|
||
)
|
||
port map (
|
||
clk => sysclk,
|
||
ena_1mhz => ena_1mhz,
|
||
ena_1mhz_2 => open
|
||
);
|
||
|
||
my1Khz : entity work.chameleon_1khz
|
||
port map (
|
||
clk => sysclk,
|
||
ena_1mhz => ena_1mhz,
|
||
ena_1khz => ena_1khz
|
||
);
|
||
|
||
-- -----------------------------------------------------------------------
|
||
-- Phi 2
|
||
-- -----------------------------------------------------------------------
|
||
myPhi2: entity work.chameleon_phi_clock
|
||
port map (
|
||
clk => sysclk,
|
||
phiIn => phi2,
|
||
|
||
-- no_clock is high when there are no phiIn changes detected.
|
||
-- This signal allows switching between real I/O and internal emulation.
|
||
no_clock => no_clock,
|
||
|
||
-- docking_station is high when there are no phiIn changes (no_clock) and
|
||
-- the phi signal is low. Without docking station phi is pulled up.
|
||
docking_station => docking_station
|
||
);
|
||
|
||
phi2 <= not phi2_n;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
-- Docking station
|
||
-- -----------------------------------------------------------------------
|
||
myDockingStation : entity work.chameleon_docking_station
|
||
port map (
|
||
clk => sysclk,
|
||
ena_1mhz => ena_1mhz,
|
||
enable => docking_ena,
|
||
|
||
docking_station => docking_station,
|
||
|
||
dotclock_n => dotclock_n,
|
||
io_ef_n => ioef_n,
|
||
rom_lh_n => romlh_n,
|
||
irq_d => irq_n,
|
||
irq_q => docking_irq,
|
||
|
||
joystick1 => docking_joystick1,
|
||
joystick2 => docking_joystick2,
|
||
joystick3 => docking_joystick3,
|
||
joystick4 => docking_joystick4,
|
||
keys => open,
|
||
restore_key_n => open,
|
||
|
||
amiga_power_led => '0',
|
||
amiga_drive_led => '0',
|
||
amiga_reset_n => open,
|
||
amiga_scancode => open
|
||
);
|
||
|
||
-- -----------------------------------------------------------------------
|
||
-- MUX CPLD
|
||
-- -----------------------------------------------------------------------
|
||
-- MUX clock
|
||
process(sysclk)
|
||
begin
|
||
if rising_edge(sysclk) then
|
||
mux_clk_reg <= not mux_clk_reg;
|
||
end if;
|
||
end process;
|
||
|
||
-- MUX read
|
||
process(sysclk)
|
||
begin
|
||
if rising_edge(sysclk) then
|
||
if mux_clk_reg = '1' then
|
||
case mux_reg is
|
||
when X"6" =>
|
||
irq_n <= mux_q(2);
|
||
when X"B" =>
|
||
--reset_button_n <= mux_q(1);
|
||
--ir <= mux_q(3);
|
||
when X"A" =>
|
||
--vga_id <= mux_q;
|
||
when X"E" =>
|
||
ps2_keyboard_dat_in <= mux_q(0);
|
||
ps2_keyboard_clk_in <= mux_q(1);
|
||
--ps2_mouse_dat_in <= mux_q(2);
|
||
--ps2_mouse_clk_in <= mux_q(3);
|
||
when others =>
|
||
null;
|
||
end case;
|
||
end if;
|
||
end if;
|
||
end process;
|
||
|
||
-- MUX write
|
||
process(sysclk)
|
||
begin
|
||
if rising_edge(sysclk) then
|
||
docking_ena <= '0';
|
||
if mux_clk_reg = '1' then
|
||
case mux_reg is
|
||
when X"7" =>
|
||
mux_d_reg <= "1111";
|
||
if docking_station = '1' then
|
||
mux_d_reg <= "1" & docking_irq & "11";
|
||
end if;
|
||
mux_reg <= X"6";
|
||
when X"6" =>
|
||
mux_d_reg <= "1111";
|
||
mux_reg <= X"8";
|
||
when X"8" =>
|
||
mux_d_reg <= "1111";
|
||
mux_reg <= X"A";
|
||
when X"A" =>
|
||
mux_d_reg <= "10" & led_green & led_red;
|
||
mux_reg <= X"B";
|
||
when X"B" =>
|
||
--mux_d_reg <= iec_reg;
|
||
mux_d_reg <= "1111";
|
||
mux_reg <= X"D";
|
||
docking_ena <= '1';
|
||
when X"D" =>
|
||
--mux_d_reg(0) <= ps2_keyboard_dat_out;
|
||
--mux_d_reg(1) <= ps2_keyboard_clk_out;
|
||
--mux_d_reg(2) <= ps2_mouse_dat_out;
|
||
--mux_d_reg(3) <= ps2_mouse_clk_out;
|
||
mux_d_reg <= "1111";
|
||
mux_reg <= X"E";
|
||
when X"E" =>
|
||
mux_d_reg <= "1111";
|
||
mux_reg <= X"7";
|
||
when others =>
|
||
mux_reg <= X"B";
|
||
mux_d_reg <= "10" & led_green & led_red;
|
||
end case;
|
||
end if;
|
||
end if;
|
||
end process;
|
||
|
||
mux_clk <= mux_clk_reg;
|
||
mux_d <= mux_d_reg;
|
||
mux <= mux_reg;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
-- LEDs
|
||
-- -----------------------------------------------------------------------
|
||
myGreenLed : entity work.chameleon_led
|
||
port map (
|
||
clk => sysclk,
|
||
clk_1khz => ena_1khz,
|
||
led_on => '0',
|
||
led_blink => '1',
|
||
led => led_red,
|
||
led_1hz => led_green
|
||
);
|
||
|
||
|
||
|
||
|
||
end vhdl;
|
chameleon/build.sh | ||
---|---|---|
rm -rf build
|
||
mkdir build
|
||
cp atari800core_chameleon.vhd build
|
||
cp pll.* build
|
||
cp atari800core.sdc build
|
||
cp atari800core.cdf build
|
||
cp chameleon_* build
|
||
|
||
mkdir build/common
|
||
mkdir build/common/a8core
|
||
mkdir build/common/components
|
||
cp ../common/a8core/* ./build/common/a8core
|
||
cp ../common/components/* ./build/common/components
|
||
|
||
cd build
|
||
../makeqsf ../atari800core.qsf ./common/a8core ./common/components
|
||
|
||
quartus_sh --flow compile atari800core
|
||
chameleon/chameleon_1khz.vhd | ||
---|---|---|
-- -----------------------------------------------------------------------
|
||
--
|
||
-- Turbo Chameleon
|
||
--
|
||
-- Multi purpose FPGA expansion for the Commodore 64 computer
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
-- Copyright 2005-2011 by Peter Wendrich (pwsoft@syntiac.com)
|
||
-- http://www.syntiac.com/chameleon.html
|
||
--
|
||
-- This source file is free software: you can redistribute it and/or modify
|
||
-- it under the terms of the GNU Lesser 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/>.
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
--
|
||
-- 1 Khz clock source
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
-- clk - system clock input
|
||
-- ena_1mhz - 1 Mhz input, signal must be one cycle high each micro-second.
|
||
-- ena_1khz - 1 Khz output. Signal is one cycle '1' each 1 millisecond.
|
||
-- -----------------------------------------------------------------------
|
||
|
||
library IEEE;
|
||
use IEEE.STD_LOGIC_1164.ALL;
|
||
use IEEE.numeric_std.all;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
|
||
entity chameleon_1khz is
|
||
port (
|
||
clk : in std_logic;
|
||
ena_1mhz : in std_logic;
|
||
|
||
ena_1khz : out std_logic
|
||
);
|
||
end entity;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
|
||
architecture rtl of chameleon_1khz is
|
||
constant maxcount : integer := 999;
|
||
signal cnt : integer range 0 to maxcount := maxcount;
|
||
|
||
signal ena_out : std_logic := '0';
|
||
begin
|
||
ena_1khz <= ena_out;
|
||
|
||
process(clk)
|
||
begin
|
||
if rising_edge(clk) then
|
||
ena_out <= '0';
|
||
if ena_1mhz = '1' then
|
||
if cnt = 0 then
|
||
cnt <= maxcount;
|
||
ena_out <= '1';
|
||
else
|
||
cnt <= cnt - 1;
|
||
end if;
|
||
end if;
|
||
end if;
|
||
end process;
|
||
end architecture;
|
chameleon/chameleon_1mhz.vhd | ||
---|---|---|
-- -----------------------------------------------------------------------
|
||
--
|
||
-- Turbo Chameleon
|
||
--
|
||
-- Multi purpose FPGA expansion for the Commodore 64 computer
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
-- Copyright 2005-2011 by Peter Wendrich (pwsoft@syntiac.com)
|
||
-- http://www.syntiac.com/chameleon.html
|
||
--
|
||
-- This source file is free software: you can redistribute it and/or modify
|
||
-- it under the terms of the GNU Lesser 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/>.
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
--
|
||
-- 1 Mhz clock source
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
-- clk - system clock input
|
||
-- ena_1mhz - 1 Mhz output. Signal is one cycle '1' each micro-second.
|
||
-- -----------------------------------------------------------------------
|
||
|
||
library IEEE;
|
||
use IEEE.STD_LOGIC_1164.ALL;
|
||
use IEEE.numeric_std.all;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
|
||
entity chameleon_1mhz is
|
||
generic (
|
||
-- Timer calibration. Clock speed in Mhz.
|
||
clk_ticks_per_usec : integer
|
||
);
|
||
port (
|
||
clk : in std_logic;
|
||
|
||
ena_1mhz : out std_logic;
|
||
ena_1mhz_2 : out std_logic
|
||
);
|
||
end entity;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
|
||
architecture rtl of chameleon_1mhz is
|
||
constant maxcount : integer := clk_ticks_per_usec-1;
|
||
signal cnt : integer range 0 to maxcount := maxcount;
|
||
signal ena_out : std_logic := '0';
|
||
signal ena2_out : std_logic := '0';
|
||
begin
|
||
ena_1mhz <= ena_out;
|
||
ena_1mhz_2 <= ena2_out;
|
||
|
||
process(clk)
|
||
begin
|
||
if rising_edge(clk) then
|
||
ena_out <= '0';
|
||
if cnt = 0 then
|
||
cnt <= maxcount;
|
||
ena_out <= '1';
|
||
else
|
||
cnt <= cnt - 1;
|
||
end if;
|
||
end if;
|
||
end process;
|
||
|
||
process(clk)
|
||
begin
|
||
if rising_edge(clk) then
|
||
ena2_out <= '0';
|
||
if cnt = (maxcount / 2) then
|
||
ena2_out <= '1';
|
||
end if;
|
||
end if;
|
||
end process;
|
||
end architecture;
|
chameleon/chameleon_docking_station.vhd | ||
---|---|---|
-- -----------------------------------------------------------------------
|
||
--
|
||
-- Turbo Chameleon
|
||
--
|
||
-- Multi purpose FPGA expansion for the Commodore 64 computer
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
-- Copyright 2005-2011 by Peter Wendrich (pwsoft@syntiac.com)
|
||
-- All Rights Reserved.
|
||
--
|
||
-- http://www.syntiac.com/chameleon.html
|
||
-- -----------------------------------------------------------------------
|
||
--
|
||
-- Chameleon docking station
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
-- clk - system clock
|
||
-- enable - must be cycle high to advance statemachine (sync with MUX)
|
||
-- ena_1mhz - must be one cycle high each micro-second. Used for timers.
|
||
|
||
-- -----------------------------------------------------------------------
|
||
|
||
library IEEE;
|
||
use IEEE.STD_LOGIC_1164.ALL;
|
||
use IEEE.numeric_std.all;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
|
||
entity chameleon_docking_station is
|
||
port (
|
||
clk : in std_logic;
|
||
enable : in std_logic;
|
||
ena_1mhz : in std_logic;
|
||
|
||
docking_station : in std_logic;
|
||
|
||
dotclock_n : in std_logic;
|
||
io_ef_n : in std_logic;
|
||
rom_lh_n : in std_logic;
|
||
irq_d : in std_logic;
|
||
irq_q : out std_logic;
|
||
|
||
joystick1 : out unsigned(5 downto 0);
|
||
joystick2 : out unsigned(5 downto 0);
|
||
joystick3 : out unsigned(5 downto 0);
|
||
joystick4 : out unsigned(5 downto 0);
|
||
-- 0 = col0, row0
|
||
-- 1 = col1, row0
|
||
-- 8 = col0, row1
|
||
-- 63 = col7, row7
|
||
keys : out unsigned(63 downto 0);
|
||
restore_key_n : out std_logic;
|
||
|
||
-- Amiga keyboard
|
||
amiga_power_led : in std_logic;
|
||
amiga_drive_led : in std_logic;
|
||
amiga_reset_n : out std_logic;
|
||
amiga_trigger : out std_logic;
|
||
amiga_scancode : out unsigned(7 downto 0)
|
||
);
|
||
end entity;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
|
||
architecture rtl of chameleon_docking_station is
|
||
constant shift_reg_bits : integer := 13*8;
|
||
signal shift_reg : unsigned(shift_reg_bits-1 downto 0);
|
||
signal bit_cnt : unsigned(7 downto 0) := (others => '0');
|
||
signal once : std_logic := '0';
|
||
|
||
signal key_reg : unsigned(63 downto 0) := (others => '1');
|
||
signal restore_n_reg : std_logic := '1';
|
||
signal joystick1_reg : unsigned(5 downto 0) := (others => '0');
|
||
signal joystick2_reg : unsigned(5 downto 0) := (others => '0');
|
||
signal joystick3_reg : unsigned(5 downto 0) := (others => '0');
|
||
signal joystick4_reg : unsigned(5 downto 0) := (others => '0');
|
||
signal dotclock_n_reg : std_logic := '0';
|
||
signal dotclock_n_dly : std_logic := '0';
|
||
signal io_ef_n_reg : std_logic := '0';
|
||
signal rom_lh_n_reg : std_logic := '1';
|
||
signal irq_q_reg : std_logic := '1';
|
||
|
||
signal amiga_reset_n_reg : std_logic := '0';
|
||
signal amiga_trigger_reg : std_logic := '0';
|
||
signal amiga_scancode_reg : unsigned(7 downto 0) := (others => '0');
|
||
begin
|
||
joystick1 <= joystick1_reg;
|
||
joystick2 <= joystick2_reg;
|
||
joystick3 <= joystick3_reg;
|
||
joystick4 <= joystick4_reg;
|
||
keys <= key_reg;
|
||
restore_key_n <= restore_n_reg;
|
||
amiga_reset_n <= amiga_reset_n_reg;
|
||
amiga_trigger <= amiga_trigger_reg;
|
||
amiga_scancode <= amiga_scancode_reg;
|
||
irq_q <= irq_q_reg;
|
||
|
||
--
|
||
-- Sample DotClock, IO_EF and ROM_LH input.
|
||
process(clk) is
|
||
begin
|
||
if rising_edge(clk) then
|
||
dotclock_n_reg <= dotclock_n;
|
||
dotclock_n_dly <= dotclock_n_reg;
|
||
io_ef_n_reg <= io_ef_n;
|
||
rom_lh_n_reg <= rom_lh_n;
|
||
end if;
|
||
end process;
|
||
|
||
--
|
||
-- Receive serial stream
|
||
process(clk) is
|
||
begin
|
||
if rising_edge(clk) then
|
||
if (dotclock_n_reg = '0') and (dotclock_n_dly = '1') then
|
||
shift_reg <= (not rom_lh_n_reg) & shift_reg(shift_reg'high downto 1);
|
||
bit_cnt <= bit_cnt + 1;
|
||
end if;
|
||
if (io_ef_n_reg = '1') and (bit_cnt >= shift_reg_bits) then
|
||
-- Word trigger. Signals start of serial bit-stream.
|
||
bit_cnt <= (others => '0');
|
||
end if;
|
||
end if;
|
||
end process;
|
||
|
||
--
|
||
-- Amiga keyboard LED control
|
||
process(clk) is
|
||
begin
|
||
if rising_edge(clk) then
|
||
irq_q_reg <= '1';
|
||
if (bit_cnt >= 40) and (bit_cnt < 56) then
|
||
irq_q_reg <= amiga_power_led;
|
||
end if;
|
||
if (bit_cnt >= 72) and (bit_cnt < 88) then
|
||
irq_q_reg <= amiga_drive_led;
|
||
end if;
|
||
end if;
|
||
end process;
|
||
|
||
--
|
||
-- Decode bytes
|
||
process(clk) is
|
||
begin
|
||
if rising_edge(clk) then
|
||
if bit_cnt = shift_reg_bits then
|
||
-- Map shifted bits to joysticks
|
||
joystick1_reg <= shift_reg(101 downto 96);
|
||
joystick2_reg <= shift_reg(85 downto 80);
|
||
joystick3_reg <= shift_reg(102)& shift_reg(103) & shift_reg(92) & shift_reg(93) & shift_reg(94) & shift_reg(95);
|
||
joystick4_reg <= shift_reg(86) & shift_reg(87) & shift_reg(88) & shift_reg(89) & shift_reg(90) & shift_reg(91);
|
||
restore_n_reg <= shift_reg(1);
|
||
|
||
-- Map shifted bits to C64 keyboard
|
||
if (shift_reg(87 downto 80) = X"FF") and (shift_reg(103 downto 96) = X"FF") then
|
||
for row in 0 to 7 loop
|
||
for col in 0 to 7 loop
|
||
-- uC scans column wise.
|
||
key_reg(row*8 + col) <= shift_reg(16 + col*8 + row);
|
||
end loop;
|
||
end loop;
|
||
else
|
||
-- Prevent conflict between keyboard and joystick.
|
||
-- Relase all keyboard keys while joystick button(s) are pressed.
|
||
key_reg <= (others => '1');
|
||
end if;
|
||
|
||
-- Amiga keyboard
|
||
amiga_reset_n_reg <= shift_reg(2);
|
||
if shift_reg(0) = '1' then
|
||
amiga_scancode_reg <= shift_reg(15 downto 8);
|
||
amiga_trigger_reg <= once;
|
||
end if;
|
||
once <= '0';
|
||
end if;
|
||
if (io_ef_n_reg = '1') then
|
||
once <= '1';
|
||
end if;
|
||
|
||
-- No docking station connected.
|
||
-- Disable all outputs to prevent conflicts.
|
||
if docking_station = '0' then
|
||
joystick1_reg <= (others => '1');
|
||
joystick2_reg <= (others => '1');
|
||
joystick3_reg <= (others => '1');
|
||
joystick4_reg <= (others => '1');
|
||
key_reg <= (others => '1');
|
||
restore_n_reg <= '1';
|
||
amiga_reset_n_reg <= '1';
|
||
end if;
|
||
end if;
|
||
end process;
|
||
end architecture;
|
chameleon/chameleon_led.vhd | ||
---|---|---|
-- -----------------------------------------------------------------------
|
||
--
|
||
-- Turbo Chameleon
|
||
--
|
||
-- Multi purpose FPGA expansion for the Commodore 64 computer
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
-- Copyright 2005-2011 by Peter Wendrich (pwsoft@syntiac.com)
|
||
-- All Rights Reserved.
|
||
--
|
||
-- Your allowed to re-use this file for non-commercial applications
|
||
-- developed for the Turbo Chameleon 64 cartridge. Either open or closed
|
||
-- source whatever might be required by other licenses.
|
||
--
|
||
-- http://www.syntiac.com/chameleon.html
|
||
-- -----------------------------------------------------------------------
|
||
--
|
||
-- LED blinker. Blink frequency 2 Hz
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
-- clk - system clock input
|
||
-- clk_1khz - 1 Khz clock input
|
||
-- led_on - if high the LED is on
|
||
-- led_blink - if high the LED is blinking
|
||
-- led - led output (high is on) 2hz
|
||
-- led_1hz - led output 1 hz
|
||
-- -----------------------------------------------------------------------
|
||
|
||
library IEEE;
|
||
use IEEE.STD_LOGIC_1164.ALL;
|
||
use IEEE.numeric_std.all;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
|
||
entity chameleon_led is
|
||
port (
|
||
clk : in std_logic;
|
||
clk_1khz : in std_logic;
|
||
|
||
led_on : in std_logic;
|
||
led_blink : in std_logic;
|
||
led : out std_logic;
|
||
led_1hz : out std_logic
|
||
);
|
||
end entity;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
|
||
architecture rtl of chameleon_led is
|
||
signal count : unsigned(9 downto 0);
|
||
begin
|
||
led <= count(8);
|
||
led_1hz <= count(9);
|
||
|
||
process(clk)
|
||
begin
|
||
if rising_edge(clk) then
|
||
if clk_1khz = '1' then
|
||
count <= count + 1;
|
||
end if;
|
||
if led_blink = '0' then
|
||
count(8) <= led_on;
|
||
count(9) <= led_on;
|
||
end if;
|
||
end if;
|
||
end process;
|
||
end architecture;
|
chameleon/chameleon_phi_clock_a.vhd | ||
---|---|---|
-- -----------------------------------------------------------------------
|
||
--
|
||
-- VGA-64
|
||
--
|
||
-- Multi purpose FPGA expansion for the Commodore 64 computer
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
-- Copyright 2005-2010 by Peter Wendrich (pwsoft@syntiac.com)
|
||
-- http://www.syntiac.com/chameleon.html
|
||
-- -----------------------------------------------------------------------
|
||
--
|
||
-- C64 Phi2-clock regeneration and divider
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
|
||
library IEEE;
|
||
use IEEE.STD_LOGIC_1164.ALL;
|
||
use IEEE.numeric_std.all;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
|
||
architecture rtl of chameleon_phi_clock is
|
||
--constant phaseShift : integer := 5; -- Number of cycles that FPGA runs ahead of measured phi.
|
||
constant phaseShift : integer := 8; -- Number of cycles that FPGA runs ahead of measured phi.
|
||
constant guardBits : integer := 4; -- Extra bits to reduce rounding errors in calculations
|
||
signal phiReg1 : std_logic;
|
||
signal phiReg2 : std_logic;
|
||
signal phiReg3 : std_logic;
|
||
signal phiSync : boolean;
|
||
|
||
signal locCnt : unsigned(7 downto 0) := (others => '0');
|
||
signal fracCnt : unsigned(guardBits-1 downto 0) := (others => '0');
|
||
signal c64Cnt : unsigned(7 downto 0) := (others => '0');
|
||
signal slvCnt : unsigned(7 downto 0) := (others => '0');
|
||
|
||
signal avgDelta : signed(8 downto 0) := (others => '0');
|
||
signal avgLen : unsigned((7+guardBits) downto 0) := (others => '0');
|
||
|
||
signal localPreHalf : std_logic := '0';
|
||
signal localHalf : std_logic := '0';
|
||
signal localPreEnd : std_logic := '0';
|
||
signal localEnd : std_logic := '0';
|
||
|
||
signal localPhi : std_logic := '0';
|
||
|
||
signal localPost1 : std_logic := '0';
|
||
signal localPost2 : std_logic := '0';
|
||
signal localPost3 : std_logic := '0';
|
||
signal localPost4 : std_logic := '0';
|
||
begin
|
||
-- Copy of input phi (deglitched)
|
||
phiBuffer <= phiReg3;
|
||
|
||
-- Average phi length
|
||
phiLength <= avgLen((7+guardBits) downto guardBits);
|
||
|
||
-- Local generated phi
|
||
phiLocal <= localPhi;
|
||
|
||
-- Cycle counter (add 1 to max-counter for each Mhz system clock)
|
||
-- For 100Mhz the cycle-counter runs to about 97 (NTSC) or 102 (PAL)
|
||
phiCnt <= locCnt;
|
||
phiPreHalf <= localPreHalf;
|
||
phiHalf <= localHalf;
|
||
phiPreEnd <= localPreEnd;
|
||
phiEnd <= localEnd;
|
||
|
||
phiPost1 <= localPost1;
|
||
phiPost2 <= localPost2;
|
||
phiPost3 <= localPost3;
|
||
phiPost4 <= localPost4;
|
||
|
||
-- Input clock synchronizer
|
||
process(clk) is
|
||
begin
|
||
if rising_edge(clk) then
|
||
phiReg1 <= phiIn;
|
||
phiReg2 <= phiReg1;
|
||
phiReg3 <= phiReg2;
|
||
end if;
|
||
end process;
|
||
phiSync <= (phiReg1 = '0') and (phiReg2 = '0') and (phiReg3 = '1');
|
||
|
||
-- Determine cycle length
|
||
process(clk) is
|
||
begin
|
||
if rising_edge(clk) then
|
||
no_clock <= '0';
|
||
docking_station <= '0';
|
||
avgDelta <= (others => '0');
|
||
avgLen <= unsigned(signed(avgLen) + avgDelta);
|
||
|
||
if (not c64Cnt) /= 0 then
|
||
c64Cnt <= c64Cnt + 1;
|
||
else
|
||
-- No Sync? Use internal speed.
|
||
|
||
-- Values for avgLen are determined experimentally using the testbench to measure actually speed.
|
||
-- Higher numbers slow down clock. Lower numbers speed clock up. Try a few times until optimum is reached
|
||
-- for particular system clock (100 Mhz at time of writing). Clocks can be accurate to atleast 3 digits with 4 guard bits.
|
||
-- PAL mode 0.985248 Mhz
|
||
avgLen <= to_unsigned(1703, 8+guardBits);
|
||
if mode = '1' then
|
||
-- NTSC mode 1.022727 Mhz
|
||
avgLen <= to_unsigned(1643, 8+guardBits);
|
||
end if;
|
||
if (phiReg1 = '0') and (phiReg2 = '0') and (phiReg3 = '0') then
|
||
docking_station <= '1';
|
||
end if;
|
||
no_clock <= '1';
|
||
end if;
|
||
if phiSync then
|
||
avgDelta <= signed("0" & c64Cnt) - signed("0" & avgLen((7+guardBits) downto guardBits));
|
||
c64Cnt <= (others => '0');
|
||
end if;
|
||
end if;
|
||
end process;
|
||
|
||
process(clk) is
|
||
begin
|
||
if rising_edge(clk) then
|
||
localPost1 <= localHalf or localEnd;
|
||
localPost2 <= localPost1;
|
||
localPost3 <= localPost2;
|
||
localPost4 <= localPost3;
|
||
end if;
|
||
end process;
|
||
|
||
process(clk) is
|
||
variable newFrac : unsigned(fracCnt'high+1 downto fracCnt'low);
|
||
begin
|
||
if rising_edge(clk) then
|
||
localPreHalf <= '0';
|
||
localHalf <= localPreHalf;
|
||
localPreEnd <= '0';
|
||
localEnd <= localPreEnd;
|
||
|
||
locCnt <= locCnt + 1;
|
||
if slvCnt >= avgLen((7+guardBits) downto guardBits) then
|
||
slvCnt <= (others => '0');
|
||
else
|
||
slvCnt <= slvCnt + 1;
|
||
end if;
|
||
|
||
if (slvCnt + phaseShift) = avgLen((7+guardBits) downto (1+guardBits)) then
|
||
localPreHalf <= '1';
|
||
end if;
|
||
if (slvCnt + phaseShift) = avgLen((7+guardBits) downto guardBits)
|
||
and localPhi = '1' then
|
||
localPreEnd <= '1';
|
||
end if;
|
||
if localHalf = '1' then
|
||
localPhi <= '1';
|
||
end if;
|
||
if localEnd = '1' then
|
||
-- Add fractional part to clock counter to have higher precision
|
||
newFrac := ("0" & fracCnt) + ("0" & (not avgLen(guardBits-1 downto 0)));
|
||
fracCnt <= newFrac(fracCnt'range);
|
||
|
||
localPhi <= '0';
|
||
locCnt <= (others => '0');
|
||
slvCnt <= c64Cnt + ("0000000" & newFrac(newFrac'high));
|
||
end if;
|
||
end if;
|
||
end process;
|
||
end architecture;
|
chameleon/chameleon_phi_clock_e.vhd | ||
---|---|---|
-- -----------------------------------------------------------------------
|
||
--
|
||
-- VGA-64
|
||
--
|
||
-- Multi purpose FPGA expansion for the Commodore 64 computer
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
-- Copyright 2005-2010 by Peter Wendrich (pwsoft@syntiac.com)
|
||
-- http://www.syntiac.com/chameleon.html
|
||
-- -----------------------------------------------------------------------
|
||
--
|
||
-- C64 Phi2-clock regeneration and divider
|
||
--
|
||
-- -----------------------------------------------------------------------
|
||
|
||
library IEEE;
|
||
use IEEE.STD_LOGIC_1164.ALL;
|
||
use IEEE.numeric_std.all;
|
||
|
||
-- -----------------------------------------------------------------------
|
||
|
||
entity chameleon_phi_clock is
|
||
port (
|
||
clk : in std_logic;
|
||
phiIn : in std_logic;
|
||
|
||
-- Standalone mode, 0=PAL and 1=NTSC
|
||
mode : in std_logic := '0';
|
||
|
||
-- Buffered phiIn (delayed)
|
||
phiBuffer : out std_logic;
|
||
phiLength : out unsigned(7 downto 0);
|
||
|
||
-- no_clock is high when there are no phiIn changes detected.
|
||
-- This signal allows switching between real I/O and internal emulation.
|
||
no_clock : out std_logic;
|
||
|
||
-- docking_station is high when there are no phiIn changes (no_clock) and
|
||
-- the phi signal is low. Without docking station phi is pulled up.
|
||
docking_station : out std_logic;
|
||
|
||
-- Resynthesised Phi2 clock
|
||
phiLocal : out std_logic;
|
||
-- Cycle counter
|
||
phiCnt : out unsigned(7 downto 0);
|
||
-- Control pulses
|
||
phiPreHalf : out std_logic;
|
||
phiHalf : out std_logic;
|
||
phiPreEnd : out std_logic;
|
||
phiEnd : out std_logic;
|
||
|
||
-- First cycle where phiLocal is changed.
|
||
phiPost1 : out std_logic;
|
||
-- Second cycle after phiLocal change.
|
||
phiPost2 : out std_logic;
|
||
-- Third cycle after phiLocal change.
|
||
phiPost3 : out std_logic;
|
||
-- Forth cycle after phiLocal change.
|
||
phiPost4 : out std_logic
|
||
);
|
||
end entity;
|
||
|
||
|
chameleon/hwtest_readme.txt | ||
---|---|---|
The chameleon_* files are taken from the hwtest2 project for the Chameleon.
|
||
They are under the lgpl license, which I believe allows linking, such as it is in hardware...
|
||
---
|
||
Hi,
|
||
|
||
You are reading the readme of the chameleon_v5_hwtest package:
|
||
The project file and source-code for the Chameleon v5 (production) and docking-station hardware test.
|
||
|
||
It tests SDRAM, IR eye, PS/2 ports, buttons, VGA DACs, stereo audio output and IEC bus.
|
||
Also can be used to test Joystick ports, keyboard connector and Amiga LEDs control on the docking-station.
|
||
Instructions on use are in the toplevel VHDL file chameleon_v5_hwtest_top.vhd
|
||
For some of the tests extra hardware is required. Wiring instructions are included.
|
||
|
||
All code except for the hardware test itself can be used and redistributed
|
||
for your own (Turbo Chameleon 64) projects. Some of the files are LGPL licensed
|
||
and can be used in a wider range of projects. See comment section in each
|
||
individual file for the license and redistibution restrictions.
|
||
|
||
I wish you all much fun experimenting with the Chameleon!
|
||
|
||
Regards,
|
||
Peter Wendrich
|
||
|
||
pwsoft@syntiac.com
|
||
http://syntiac.com/chameleon.html
|
||
|
||
|
||
|
||
|
chameleon/lgpl.txt | ||
---|---|---|
GNU LESSER GENERAL PUBLIC LICENSE
|
||
Version 3, 29 June 2007
|
||
|
||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||
Everyone is permitted to copy and distribute verbatim copies
|
||
of this license document, but changing it is not allowed.
|
||
|
||
|
||
This version of the GNU Lesser General Public License incorporates
|
||
the terms and conditions of version 3 of the GNU General Public
|
||
License, supplemented by the additional permissions listed below.
|
||
|
||
0. Additional Definitions.
|
||
|
||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||
General Public License.
|
||
|
||
"The Library" refers to a covered work governed by this License,
|
||
other than an Application or a Combined Work as defined below.
|
||
|
||
An "Application" is any work that makes use of an interface provided
|
||
by the Library, but which is not otherwise based on the Library.
|
||
Defining a subclass of a class defined by the Library is deemed a mode
|
||
of using an interface provided by the Library.
|
||
|
||
A "Combined Work" is a work produced by combining or linking an
|
||
Application with the Library. The particular version of the Library
|
||
with which the Combined Work was made is also called the "Linked
|
||
Version".
|
||
|
||
The "Minimal Corresponding Source" for a Combined Work means the
|
||
Corresponding Source for the Combined Work, excluding any source code
|
||
for portions of the Combined Work that, considered in isolation, are
|
||
based on the Application, and not on the Linked Version.
|
||
|
||
The "Corresponding Application Code" for a Combined Work means the
|
||
object code and/or source code for the Application, including any data
|
||
and utility programs needed for reproducing the Combined Work from the
|
||
Application, but excluding the System Libraries of the Combined Work.
|
||
|
||
1. Exception to Section 3 of the GNU GPL.
|
||
|
||
You may convey a covered work under sections 3 and 4 of this License
|
||
without being bound by section 3 of the GNU GPL.
|
||
|
||
2. Conveying Modified Versions.
|
||
|
||
If you modify a copy of the Library, and, in your modifications, a
|
||
facility refers to a function or data to be supplied by an Application
|
||
that uses the facility (other than as an argument passed when the
|
||
facility is invoked), then you may convey a copy of the modified
|
||
version:
|
||
|
||
a) under this License, provided that you make a good faith effort to
|
||
ensure that, in the event an Application does not supply the
|
||
function or data, the facility still operates, and performs
|
||
whatever part of its purpose remains meaningful, or
|
||
|
||
b) under the GNU GPL, with none of the additional permissions of
|
||
this License applicable to that copy.
|
||
|
||
3. Object Code Incorporating Material from Library Header Files.
|
||
|
||
The object code form of an Application may incorporate material from
|
||
a header file that is part of the Library. You may convey such object
|
||
code under terms of your choice, provided that, if the incorporated
|
||
material is not limited to numerical parameters, data structure
|
||
layouts and accessors, or small macros, inline functions and templates
|
||
(ten or fewer lines in length), you do both of the following:
|
||
|
||
a) Give prominent notice with each copy of the object code that the
|
||
Library is used in it and that the Library and its use are
|
||
covered by this License.
|
||
|
||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||
document.
|
||
|
||
4. Combined Works.
|
||
|
||
You may convey a Combined Work under terms of your choice that,
|
||
taken together, effectively do not restrict modification of the
|
||
portions of the Library contained in the Combined Work and reverse
|
||
engineering for debugging such modifications, if you also do each of
|
||
the following:
|
||
|
||
a) Give prominent notice with each copy of the Combined Work that
|
||
the Library is used in it and that the Library and its use are
|
||
covered by this License.
|
||
|
||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||
document.
|
||
|
||
c) For a Combined Work that displays copyright notices during
|
||
execution, include the copyright notice for the Library among
|
||
these notices, as well as a reference directing the user to the
|
||
copies of the GNU GPL and this license document.
|
||
|
||
d) Do one of the following:
|
||
|
||
0) Convey the Minimal Corresponding Source under the terms of this
|
||
License, and the Corresponding Application Code in a form
|
||
suitable for, and under terms that permit, the user to
|
||
recombine or relink the Application with a modified version of
|
||
the Linked Version to produce a modified Combined Work, in the
|
||
manner specified by section 6 of the GNU GPL for conveying
|
||
Corresponding Source.
|
||
|
||
1) Use a suitable shared library mechanism for linking with the
|
||
Library. A suitable mechanism is one that (a) uses at run time
|
||
a copy of the Library already present on the user's computer
|
||
system, and (b) will operate properly with a modified version
|
||
of the Library that is interface-compatible with the Linked
|
||
Version.
|
Also available in: Unified diff
First working Chameleon build. No drive emulation, 16KB RAM, PAL.