├── README.txt ├── .gitignore ├── .gitmodules ├── rtl ├── mist │ ├── cyc3 │ │ ├── rom_reconfig_ntsc.qip │ │ ├── rom_reconfig_pal.qip │ │ ├── pll_c64_reconfig.qip │ │ ├── pll.qip │ │ ├── pll_c64.qip │ │ ├── pll.ppf │ │ ├── pll_c64.ppf │ │ ├── pll_c64_ntsc.mif │ │ ├── pll_c64_pal.mif │ │ ├── rom_reconfig_pal.vhd │ │ └── rom_reconfig_ntsc.vhd │ ├── cyc4gx │ │ ├── rom_reconfig_ntsc.qip │ │ ├── rom_reconfig_pal.qip │ │ ├── pll_c64_reconfig.qip │ │ ├── pll_c64.qip │ │ ├── pll.ppf │ │ ├── pll.qip │ │ ├── pll_c64.ppf │ │ ├── pll_c64_ntsc.mif │ │ ├── pll_c64_pal.mif │ │ ├── rom_reconfig_pal.vhd │ │ └── rom_reconfig_ntsc.vhd │ ├── sigma_delta_dac.v │ ├── sdram.v │ └── c64_mist_top.sv ├── mos6526.vhd ├── sid │ ├── sid_debug_pkg.vhd │ ├── Q_table.vhd │ ├── sid_ctrl.vhd │ ├── oscillator.vhd │ ├── sid_mixer.vhd │ ├── my_math_pkg.vhd │ ├── wave_map.vhd │ ├── adsr_multi.vhd │ └── mult_acc.vhd ├── c1541 │ ├── gen_rom.vhd │ ├── spram.vhd │ └── mist_sd_card.sv ├── progressbar.v ├── fpga64_rgbcolor.vhd ├── gen_ram.vhd ├── video_vicII_656x_e.vhd ├── io_ps2_keyboard.vhd ├── cpu_6510.vhd ├── fpga64.qip ├── c64_midi.vhd ├── sid8580 │ ├── sid_filters.v │ ├── sid_envelope.v │ └── sid8580.v ├── tap_fifo.vhd ├── c1530.vhd ├── fpga64_buslogic_roms_mmu.vhd └── reu.vhd ├── clean.bat ├── C64_mist.qpf ├── C64_SiDi128.qpf ├── C64_Poseidon_CGX150.qpf └── C64_mist.sdc /README.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mist-devel/c64/HEAD/README.txt -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out/ 2 | db/ 3 | incremental_db/ 4 | output_files/ 5 | greybox_tmp 6 | PLLJ_PLLSPE_INFO.txt 7 | build_id.vhd 8 | *.qws 9 | *.bak 10 | *.jdi 11 | *.sof 12 | *.done 13 | *.pin 14 | *.rpt 15 | *.smsg 16 | *.summary 17 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "rtl/mist/mist-modules"] 2 | path = rtl/mist/mist-modules 3 | url = https://github.com/mist-devel/mist-modules.git 4 | [submodule "rtl/T65"] 5 | path = rtl/T65 6 | url = https://github.com/mist-devel/T65.git 7 | -------------------------------------------------------------------------------- /rtl/mist/cyc3/rom_reconfig_ntsc.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ROM: 1-PORT" 2 | set_global_assignment -name IP_TOOL_VERSION "13.1" 3 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "rom_reconfig_ntsc.vhd"] 4 | -------------------------------------------------------------------------------- /rtl/mist/cyc3/rom_reconfig_pal.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ROM: 1-PORT" 2 | set_global_assignment -name IP_TOOL_VERSION "13.1" 3 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "rom_reconfig_pal.vhd"] 4 | -------------------------------------------------------------------------------- /rtl/mist/cyc3/pll_c64_reconfig.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ALTPLL_RECONFIG" 2 | set_global_assignment -name IP_TOOL_VERSION "13.1" 3 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "pll_c64_reconfig.vhd"] 4 | -------------------------------------------------------------------------------- /clean.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | del /s *.bak 3 | del /s *.orig 4 | del /s *.rej 5 | rmdir /s /q db 6 | rmdir /s /q incremental_db 7 | rmdir /s /q output_files 8 | rmdir /s /q simulation 9 | del PLLJ_PLLSPE_INFO.txt 10 | del *.qws 11 | del *.ppf 12 | del *.qip 13 | pause 14 | -------------------------------------------------------------------------------- /rtl/mist/cyc3/pll.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ALTPLL" 2 | set_global_assignment -name IP_TOOL_VERSION "13.1" 3 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "pll.vhd"] 4 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll.ppf"] 5 | -------------------------------------------------------------------------------- /rtl/mist/cyc3/pll_c64.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ALTPLL" 2 | set_global_assignment -name IP_TOOL_VERSION "13.1" 3 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "pll_c64.vhd"] 4 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_c64.ppf"] 5 | -------------------------------------------------------------------------------- /rtl/mist/cyc4gx/rom_reconfig_ntsc.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ROM: 1-PORT" 2 | set_global_assignment -name IP_TOOL_VERSION "21.1" 3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV GX}" 4 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "rom_reconfig_ntsc.vhd"] 5 | -------------------------------------------------------------------------------- /rtl/mist/cyc4gx/rom_reconfig_pal.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ROM: 1-PORT" 2 | set_global_assignment -name IP_TOOL_VERSION "21.1" 3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV GX}" 4 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "rom_reconfig_pal.vhd"] 5 | -------------------------------------------------------------------------------- /rtl/mist/cyc4gx/pll_c64_reconfig.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ALTPLL_RECONFIG" 2 | set_global_assignment -name IP_TOOL_VERSION "21.1" 3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV GX}" 4 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "pll_c64_reconfig.vhd"] 5 | -------------------------------------------------------------------------------- /rtl/mist/cyc4gx/pll_c64.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ALTPLL" 2 | set_global_assignment -name IP_TOOL_VERSION "22.1" 3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV GX}" 4 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "pll_c64.vhd"] 5 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_c64.ppf"] 6 | -------------------------------------------------------------------------------- /rtl/mist/cyc3/pll.ppf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /rtl/mist/cyc4gx/pll.ppf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /rtl/mist/cyc4gx/pll.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ALTPLL" 2 | set_global_assignment -name IP_TOOL_VERSION "21.1" 3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV GX}" 4 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "pll.vhd"] 5 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_inst.vhd"] 6 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll.cmp"] 7 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll.ppf"] 8 | -------------------------------------------------------------------------------- /rtl/mos6526.vhd: -------------------------------------------------------------------------------- 1 | library IEEE; 2 | use IEEE.std_logic_1164.all; 3 | 4 | package mos6526 is 5 | component mos6526 6 | PORT ( 7 | mode : in std_logic; -- '0' - 6256, '1' - 8521 8 | clk : in std_logic; 9 | phi2_p : in std_logic; 10 | phi2_n : in std_logic; 11 | res_n : in std_logic; 12 | cs_n : in std_logic; 13 | rw : in std_logic; -- '1' - read, '0' - write 14 | rs : in std_logic_vector(3 downto 0); 15 | db_in : in std_logic_vector(7 downto 0); 16 | db_out : out std_logic_vector(7 downto 0); 17 | pa_in : in std_logic_vector(7 downto 0); 18 | pa_out : out std_logic_vector(7 downto 0); 19 | pb_in : in std_logic_vector(7 downto 0); 20 | pb_out : out std_logic_vector(7 downto 0); 21 | flag_n : in std_logic; 22 | pc_n : out std_logic; 23 | tod : in std_logic; 24 | sp_in : in std_logic; 25 | sp_out : out std_logic; 26 | cnt_in : in std_logic; 27 | cnt_out : out std_logic; 28 | irq_n : out std_logic 29 | ); 30 | end component; 31 | end package; -------------------------------------------------------------------------------- /rtl/mist/cyc3/pll_c64.ppf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /rtl/mist/cyc4gx/pll_c64.ppf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /C64_mist.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 1991-2014 Altera Corporation 4 | # Your use of Altera Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Altera Program License 10 | # Subscription Agreement, Altera MegaCore Function License 11 | # Agreement, or other applicable license agreement, including, 12 | # without limitation, that your use is for the sole purpose of 13 | # programming logic devices manufactured by Altera and sold by 14 | # Altera or its authorized distributors. Please refer to the 15 | # applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus II 64-Bit 20 | # Version 13.1.4 Build 182 03/12/2014 SJ Web Edition 21 | # Date created = 09:30:37 July 09, 2015 22 | # 23 | # -------------------------------------------------------------------------- # 24 | 25 | QUARTUS_VERSION = "13.1" 26 | DATE = "09:30:37 July 09, 2015" 27 | 28 | # Revisions 29 | 30 | PROJECT_REVISION = "C64_mist" 31 | -------------------------------------------------------------------------------- /rtl/sid/sid_debug_pkg.vhd: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | -- 3 | -- (C) COPYRIGHT 2010 Gideon's Logic Architectures' 4 | -- 5 | ------------------------------------------------------------------------------- 6 | -- 7 | -- Author: Gideon Zweijtzer (gideon.zweijtzer (at) gmail.com) 8 | -- 9 | -- Note that this file is copyrighted, and is not supposed to be used in other 10 | -- projects without written permission from the author. 11 | -- 12 | ------------------------------------------------------------------------------- 13 | 14 | library ieee; 15 | use ieee.std_logic_1164.all; 16 | use ieee.numeric_std.all; 17 | 18 | package sid_debug_pkg is 19 | 20 | type t_voice_debug is record 21 | state : unsigned(1 downto 0); 22 | enveloppe : unsigned(7 downto 0); 23 | pre15 : unsigned(14 downto 0); 24 | pre5 : unsigned(4 downto 0); 25 | presc : unsigned(14 downto 0); 26 | gate : std_logic; 27 | attack : std_logic_vector(3 downto 0); 28 | decay : std_logic_vector(3 downto 0); 29 | sustain : std_logic_vector(3 downto 0); 30 | release : std_logic_vector(3 downto 0); 31 | end record; 32 | 33 | type t_voice_debug_array is array(natural range <>) of t_voice_debug; 34 | 35 | end; 36 | -------------------------------------------------------------------------------- /C64_SiDi128.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 1991-2011 Altera Corporation 4 | # Your use of Altera Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Altera Program License 10 | # Subscription Agreement, Altera MegaCore Function License 11 | # Agreement, or other applicable license agreement, including, 12 | # without limitation, that your use is for the sole purpose of 13 | # programming logic devices manufactured by Altera and sold by 14 | # Altera or its authorized distributors. Please refer to the 15 | # applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus II 20 | # Version 10.1 Build 197 01/19/2011 Service Pack 1 SJ Full Version 21 | # Date created = 23:49:02 July 13, 2012 22 | # 23 | # -------------------------------------------------------------------------- # 24 | 25 | QUARTUS_VERSION = "10.1" 26 | DATE = "23:49:02 July 13, 2012" 27 | 28 | # Revisions 29 | 30 | PROJECT_REVISION = "C64_SiDi128" 31 | -------------------------------------------------------------------------------- /C64_Poseidon_CGX150.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 1991-2011 Altera Corporation 4 | # Your use of Altera Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Altera Program License 10 | # Subscription Agreement, Altera MegaCore Function License 11 | # Agreement, or other applicable license agreement, including, 12 | # without limitation, that your use is for the sole purpose of 13 | # programming logic devices manufactured by Altera and sold by 14 | # Altera or its authorized distributors. Please refer to the 15 | # applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus II 20 | # Version 10.1 Build 197 01/19/2011 Service Pack 1 SJ Full Version 21 | # Date created = 23:49:02 July 13, 2012 22 | # 23 | # -------------------------------------------------------------------------- # 24 | 25 | QUARTUS_VERSION = "10.1" 26 | DATE = "23:49:02 July 13, 2012" 27 | 28 | # Revisions 29 | 30 | PROJECT_REVISION = "C64_Poseidon_CGX150" 31 | -------------------------------------------------------------------------------- /rtl/sid/Q_table.vhd: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | -- 3 | -- (C) COPYRIGHT 2010 Gideon's Logic Architectures' 4 | -- 5 | ------------------------------------------------------------------------------- 6 | -- 7 | -- Author: Gideon Zweijtzer (gideon.zweijtzer (at) gmail.com) 8 | -- 9 | -- Note that this file is copyrighted, and is not supposed to be used in other 10 | -- projects without written permission from the author. 11 | -- 12 | ------------------------------------------------------------------------------- 13 | library ieee; 14 | use ieee.std_logic_1164.all; 15 | use ieee.numeric_std.all; 16 | 17 | entity Q_table is 18 | port ( 19 | Q_reg : in unsigned(3 downto 0); 20 | filter_q : out signed(17 downto 0) ); 21 | end Q_table; 22 | 23 | architecture Gideon of Q_table is 24 | 25 | type t_18_bit_array is array(natural range <>) of signed(17 downto 0); 26 | function create_factors(max_Q: real) return t_18_bit_array is 27 | constant critical : real := 0.70710678; -- no resonance at 0.5*sqrt(2) 28 | variable q_step : real; 29 | variable q : real; 30 | variable scaled : real; 31 | variable ret : t_18_bit_array(0 to 15); 32 | begin 33 | q_step := (max_Q - critical) / 15.0; -- linear 34 | for i in 0 to 15 loop 35 | q := critical + (real(i) * q_step); 36 | scaled := 65536.0 / q; 37 | ret(i) := to_signed(integer(scaled), 18); 38 | end loop; 39 | return ret; 40 | end function; 41 | 42 | constant c_table : t_18_bit_array(0 to 15) := create_factors(1.8); 43 | begin 44 | filter_q <= c_table(to_integer(Q_reg)); 45 | end Gideon; 46 | -------------------------------------------------------------------------------- /rtl/c1541/gen_rom.vhd: -------------------------------------------------------------------------------- 1 | -- altera message_off 10306 2 | 3 | library ieee; 4 | use IEEE.std_logic_1164.all; 5 | use IEEE.std_logic_unsigned.ALL; 6 | use IEEE.numeric_std.all; 7 | 8 | entity gen_rom is 9 | 10 | generic 11 | ( 12 | INIT_FILE : string := ""; 13 | ADDR_WIDTH : natural := 14; 14 | DATA_WIDTH : natural := 8 15 | ); 16 | 17 | port 18 | ( 19 | wrclock : in std_logic; 20 | wraddress : in std_logic_vector((ADDR_WIDTH - 1) downto 0) := (others => '0'); 21 | data : in std_logic_vector((DATA_WIDTH - 1) downto 0) := (others => '0'); 22 | wren : in std_logic := '0'; 23 | 24 | rdclock : in std_logic; 25 | rdaddress : in std_logic_vector((ADDR_WIDTH - 1) downto 0); 26 | q : out std_logic_vector((DATA_WIDTH - 1) downto 0); 27 | cs : in std_logic := '1' 28 | ); 29 | 30 | end gen_rom; 31 | 32 | architecture rtl of gen_rom is 33 | 34 | subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0); 35 | type memory_t is array(2**ADDR_WIDTH-1 downto 0) of word_t; 36 | 37 | shared variable ram : memory_t; 38 | 39 | attribute ram_init_file : string; 40 | attribute ram_init_file of ram : variable is INIT_FILE; 41 | 42 | signal q0 : std_logic_vector((DATA_WIDTH - 1) downto 0); 43 | 44 | 45 | begin 46 | 47 | q<= q0 when cs = '1' else (others => '1'); 48 | 49 | -- WR Port 50 | process(wrclock) begin 51 | if(rising_edge(wrclock)) then 52 | if(wren = '1') then 53 | ram(to_integer(unsigned(wraddress))) := data; 54 | end if; 55 | end if; 56 | end process; 57 | 58 | -- RD Port 59 | process(rdclock) begin 60 | if(rising_edge(rdclock)) then 61 | q0 <= ram(to_integer(unsigned(rdaddress))); 62 | end if; 63 | end process; 64 | 65 | end rtl; 66 | -------------------------------------------------------------------------------- /rtl/sid/sid_ctrl.vhd: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | -- 3 | -- (C) COPYRIGHT 2010 Gideon's Logic Architectures' 4 | -- 5 | ------------------------------------------------------------------------------- 6 | -- 7 | -- Author: Gideon Zweijtzer (gideon.zweijtzer (at) gmail.com) 8 | -- 9 | -- Note that this file is copyrighted, and is not supposed to be used in other 10 | -- projects without written permission from the author. 11 | -- 12 | ------------------------------------------------------------------------------- 13 | library ieee; 14 | use ieee.std_logic_1164.all; 15 | use ieee.numeric_std.all; 16 | 17 | entity sid_ctrl is 18 | generic ( 19 | g_num_voices : natural := 8 ); 20 | port ( 21 | clock : in std_logic; 22 | reset : in std_logic; 23 | 24 | start_iter : in std_logic; 25 | 26 | voice_osc : out unsigned(3 downto 0); 27 | enable_osc : out std_logic ); 28 | 29 | end sid_ctrl; 30 | 31 | architecture gideon of sid_ctrl is 32 | 33 | signal voice_cnt : unsigned(3 downto 0); 34 | signal enable : std_logic; 35 | 36 | begin 37 | process(clock) 38 | begin 39 | if rising_edge(clock) then 40 | if reset='1' then 41 | voice_cnt <= X"0"; 42 | enable <= '0'; 43 | elsif start_iter='1' then 44 | voice_cnt <= X"0"; 45 | enable <= '1'; 46 | elsif voice_cnt = g_num_voices-1 then 47 | voice_cnt <= X"0"; 48 | enable <= '0'; 49 | elsif enable='1' then 50 | voice_cnt <= voice_cnt + 1; 51 | enable <= '1'; 52 | end if; 53 | end if; 54 | end process; 55 | 56 | voice_osc <= voice_cnt; 57 | enable_osc <= enable; 58 | end gideon; 59 | -------------------------------------------------------------------------------- /rtl/progressbar.v: -------------------------------------------------------------------------------- 1 | /* 2 | A simple progressbar overlay 3 | */ 4 | 5 | module progressbar ( 6 | input clk, 7 | input ce_pix, 8 | input hblank, 9 | input vblank, 10 | input enable, 11 | input [24:0] current, 12 | input [24:0] max, 13 | output pix 14 | ); 15 | 16 | parameter X_OFFSET = 11'd68; 17 | parameter Y_OFFSET = 11'd20; 18 | 19 | reg [7:0] progress; 20 | /* 21 | always @(posedge clk) begin 22 | progress <= current / max[24:7]; 23 | end 24 | */ 25 | // Without divider 26 | reg [24:0] prg_counter = 0; 27 | reg [7:0] prg_iter = 0; 28 | always @(posedge clk) begin 29 | if (prg_counter >= current) begin 30 | progress <= prg_iter; 31 | prg_counter <= 0; 32 | prg_iter <= 0; 33 | end else begin 34 | prg_counter <= prg_counter + max[24:7]; 35 | prg_iter <= prg_iter + 1'd1; 36 | end 37 | end 38 | 39 | // horizontal counter 40 | reg [10:0] h_cnt; 41 | 42 | // vertical counter 43 | reg [10:0] v_cnt; 44 | 45 | always @(posedge clk) begin 46 | reg hbD; 47 | 48 | if(ce_pix) begin 49 | hbD <= hblank; 50 | 51 | if(hblank) begin 52 | h_cnt <= 0; 53 | if (!hbD) v_cnt <= v_cnt + 1'd1; 54 | end else 55 | h_cnt <= h_cnt + 1'd1; 56 | 57 | if(vblank) v_cnt <= 0; 58 | end 59 | end 60 | 61 | // area in which OSD is being displayed 62 | wire [10:0] h_osd_start = X_OFFSET; 63 | wire [10:0] h_osd_end = h_osd_start + 8'd134; 64 | wire [10:0] v_osd_start = Y_OFFSET; 65 | wire [10:0] v_osd_end = v_osd_start + 8'd8; 66 | 67 | wire [10:0] osd_hcnt = h_cnt - h_osd_start; 68 | wire [3:0] osd_vcnt = v_cnt - v_osd_start; 69 | reg osd_de; 70 | reg osd_pixel; 71 | 72 | always @(posedge clk) begin 73 | if(ce_pix) begin 74 | case (osd_vcnt) 75 | 0,7: osd_pixel <= 1; 76 | 2,3,4,5: osd_pixel <= osd_hcnt == 0 || osd_hcnt == 132 || ((osd_hcnt - 2'd2) < progress); 77 | default: osd_pixel <= osd_hcnt == 0 || osd_hcnt == 132; 78 | endcase 79 | 80 | osd_de <= 81 | (h_cnt >= h_osd_start) && ((h_cnt + 1'd1) < h_osd_end) && 82 | (v_cnt >= v_osd_start) && (v_cnt < v_osd_end); 83 | end 84 | end 85 | 86 | assign pix = enable & osd_pixel & osd_de; 87 | 88 | endmodule 89 | -------------------------------------------------------------------------------- /rtl/fpga64_rgbcolor.vhd: -------------------------------------------------------------------------------- 1 | -- ----------------------------------------------------------------------- 2 | -- 3 | -- FPGA 64 4 | -- 5 | -- A fully functional commodore 64 implementation in a single FPGA 6 | -- 7 | -- ----------------------------------------------------------------------- 8 | -- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com) 9 | -- http://www.syntiac.com/fpga64.html 10 | -- ----------------------------------------------------------------------- 11 | -- 12 | -- C64 palette index to 24 bit RGB color 13 | -- 14 | -- ----------------------------------------------------------------------- 15 | 16 | library IEEE; 17 | use IEEE.STD_LOGIC_1164.ALL; 18 | use IEEE.numeric_std.all; 19 | 20 | -- ----------------------------------------------------------------------- 21 | 22 | entity fpga64_rgbcolor is 23 | port ( 24 | index: in unsigned(3 downto 0); 25 | r: out unsigned(7 downto 0); 26 | g: out unsigned(7 downto 0); 27 | b: out unsigned(7 downto 0) 28 | ); 29 | end fpga64_rgbcolor; 30 | 31 | -- ----------------------------------------------------------------------- 32 | 33 | architecture Behavioral of fpga64_rgbcolor is 34 | begin 35 | process(index) 36 | begin 37 | case index is 38 | when X"0" => r <= X"00"; g <= X"00"; b <= X"00"; 39 | when X"1" => r <= X"FF"; g <= X"FF"; b <= X"FF"; 40 | when X"2" => r <= X"68"; g <= X"37"; b <= X"2B"; 41 | when X"3" => r <= X"70"; g <= X"A4"; b <= X"B2"; 42 | when X"4" => r <= X"6F"; g <= X"3D"; b <= X"86"; 43 | when X"5" => r <= X"58"; g <= X"8D"; b <= X"43"; 44 | when X"6" => r <= X"35"; g <= X"28"; b <= X"79"; 45 | when X"7" => r <= X"B8"; g <= X"C7"; b <= X"6F"; 46 | when X"8" => r <= X"6F"; g <= X"4F"; b <= X"25"; 47 | when X"9" => r <= X"43"; g <= X"39"; b <= X"00"; 48 | when X"A" => r <= X"9A"; g <= X"67"; b <= X"59"; 49 | when X"B" => r <= X"44"; g <= X"44"; b <= X"44"; 50 | when X"C" => r <= X"6C"; g <= X"6C"; b <= X"6C"; 51 | when X"D" => r <= X"9A"; g <= X"D2"; b <= X"84"; 52 | when X"E" => r <= X"6C"; g <= X"5E"; b <= X"B5"; 53 | when X"F" => r <= X"95"; g <= X"95"; b <= X"95"; 54 | end case; 55 | end process; 56 | end Behavioral; 57 | -------------------------------------------------------------------------------- /rtl/c1541/spram.vhd: -------------------------------------------------------------------------------- 1 | LIBRARY ieee; 2 | USE ieee.std_logic_1164.all; 3 | 4 | LIBRARY altera_mf; 5 | USE altera_mf.all; 6 | 7 | ENTITY spram IS 8 | GENERIC 9 | ( 10 | init_file : string := ""; 11 | numwords_a : natural := 0; -- not used 12 | widthad_a : natural; 13 | width_a : natural := 8; 14 | outdata_reg_a : string := "UNREGISTERED" 15 | ); 16 | PORT 17 | ( 18 | address : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0); 19 | clock : IN STD_LOGIC ; 20 | data : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0); 21 | wren : IN STD_LOGIC ; 22 | q : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0) 23 | ); 24 | END spram; 25 | 26 | ARCHITECTURE SYN OF spram IS 27 | 28 | SIGNAL sub_wire0 : STD_LOGIC_VECTOR (width_a-1 DOWNTO 0); 29 | 30 | COMPONENT altsyncram 31 | GENERIC ( 32 | clock_enable_input_a : STRING; 33 | clock_enable_output_a : STRING; 34 | init_file : STRING; 35 | intended_device_family : STRING; 36 | lpm_hint : STRING; 37 | lpm_type : STRING; 38 | numwords_a : NATURAL; 39 | operation_mode : STRING; 40 | outdata_aclr_a : STRING; 41 | outdata_reg_a : STRING; 42 | power_up_uninitialized : STRING; 43 | widthad_a : NATURAL; 44 | width_a : NATURAL; 45 | width_byteena_a : NATURAL 46 | ); 47 | PORT ( 48 | wren_a : IN STD_LOGIC ; 49 | clock0 : IN STD_LOGIC ; 50 | address_a : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0); 51 | q_a : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0); 52 | data_a : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0) 53 | ); 54 | END COMPONENT; 55 | 56 | BEGIN 57 | q <= sub_wire0(width_a-1 DOWNTO 0); 58 | 59 | altsyncram_component : altsyncram 60 | GENERIC MAP ( 61 | clock_enable_input_a => "BYPASS", 62 | clock_enable_output_a => "BYPASS", 63 | init_file => init_file, 64 | intended_device_family => "Cyclone II", 65 | lpm_hint => "ENABLE_RUNTIME_MOD=NO", 66 | lpm_type => "altsyncram", 67 | numwords_a => 2**widthad_a, 68 | operation_mode => "SINGLE_PORT", 69 | outdata_aclr_a => "NONE", 70 | outdata_reg_a => outdata_reg_a, 71 | power_up_uninitialized => "FALSE", 72 | widthad_a => widthad_a, 73 | width_a => width_a, 74 | width_byteena_a => 1 75 | ) 76 | PORT MAP ( 77 | wren_a => wren, 78 | clock0 => clock, 79 | address_a => address, 80 | data_a => data, 81 | q_a => sub_wire0 82 | ); 83 | 84 | END SYN; 85 | -------------------------------------------------------------------------------- /rtl/gen_ram.vhd: -------------------------------------------------------------------------------- 1 | -- ----------------------------------------------------------------------- 2 | -- 3 | -- Syntiac's generic VHDL support files. 4 | -- 5 | -- ----------------------------------------------------------------------- 6 | -- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com) 7 | -- http://www.syntiac.com/fpga64.html 8 | -- ----------------------------------------------------------------------- 9 | -- 10 | -- gen_rwram.vhd 11 | -- 12 | -- ----------------------------------------------------------------------- 13 | -- 14 | -- generic ram. 15 | -- 16 | -- ----------------------------------------------------------------------- 17 | 18 | library IEEE; 19 | use IEEE.STD_LOGIC_1164.ALL; 20 | use IEEE.numeric_std.ALL; 21 | 22 | -- ----------------------------------------------------------------------- 23 | 24 | entity gen_ram is 25 | generic ( 26 | dWidth : integer := 8; 27 | aWidth : integer := 10 28 | ); 29 | port ( 30 | clk : in std_logic; 31 | we : in std_logic; 32 | addr : in unsigned((aWidth-1) downto 0); 33 | d : in unsigned((dWidth-1) downto 0); 34 | q : out unsigned((dWidth-1) downto 0) 35 | ); 36 | end entity; 37 | 38 | -- ----------------------------------------------------------------------- 39 | 40 | architecture rtl of gen_ram is 41 | subtype addressRange is integer range 0 to ((2**aWidth)-1); 42 | type ramDef is array(addressRange) of unsigned((dWidth-1) downto 0); 43 | signal ram: ramDef; 44 | 45 | signal rAddrReg : unsigned((aWidth-1) downto 0); 46 | signal qReg : unsigned((dWidth-1) downto 0); 47 | begin 48 | -- ----------------------------------------------------------------------- 49 | -- Signals to entity interface 50 | -- ----------------------------------------------------------------------- 51 | q <= qReg; 52 | 53 | -- ----------------------------------------------------------------------- 54 | -- Memory write 55 | -- ----------------------------------------------------------------------- 56 | process(clk) 57 | begin 58 | if rising_edge(clk) then 59 | if we = '1' then 60 | ram(to_integer(addr)) <= d; 61 | end if; 62 | end if; 63 | end process; 64 | 65 | -- ----------------------------------------------------------------------- 66 | -- Memory read 67 | -- ----------------------------------------------------------------------- 68 | process(clk) 69 | begin 70 | if rising_edge(clk) then 71 | qReg <= ram(to_integer(rAddrReg)); 72 | rAddrReg <= addr; 73 | end if; 74 | end process; 75 | end architecture; 76 | 77 | -------------------------------------------------------------------------------- /rtl/video_vicII_656x_e.vhd: -------------------------------------------------------------------------------- 1 | -- ----------------------------------------------------------------------- 2 | -- 3 | -- FPGA 64 4 | -- 5 | -- A fully functional commodore 64 implementation in a single FPGA 6 | -- 7 | -- ----------------------------------------------------------------------- 8 | -- Peter Wendrich (pwsoft@syntiac.com) 9 | -- http://www.syntiac.com/fpga64.html 10 | -- ----------------------------------------------------------------------- 11 | -- 12 | -- VIC-II - Video Interface Chip no 2 13 | -- 14 | -- ----------------------------------------------------------------------- 15 | 16 | library IEEE; 17 | use IEEE.STD_LOGIC_1164.ALL; 18 | use IEEE.numeric_std.ALL; 19 | 20 | -- ----------------------------------------------------------------------- 21 | 22 | entity video_vicii_656x is 23 | generic ( 24 | registeredAddress : boolean; 25 | emulateRefresh : boolean := false; 26 | emulateLightpen : boolean := false; 27 | emulateGraphics : boolean := true 28 | ); 29 | port ( 30 | clk: in std_logic; 31 | -- phi = 0 is VIC cycle 32 | -- phi = 1 is CPU cycle (only used by VIC when BA is low) 33 | phi : in std_logic; 34 | enaData : in std_logic; 35 | enaPixel : in std_logic; 36 | 37 | baSync : in std_logic; 38 | ba: out std_logic; 39 | 40 | turbo_reg_en : in std_logic; 41 | turbo_switch : out unsigned(1 downto 0); 42 | 43 | mode6569 : in std_logic; -- PAL 63 cycles and 312 lines 44 | mode6567old : in std_logic; -- old NTSC 64 cycles and 262 line 45 | mode6567R8 : in std_logic; -- new NTSC 65 cycles and 263 line 46 | mode6572 : in std_logic; -- PAL-N 65 cycles and 312 lines 47 | 48 | variant : in std_logic_vector(1 downto 0); -- 00 - NMOS, 01 - HMOS, 10 - old HMOS 49 | reset : in std_logic; 50 | cs : in std_logic; 51 | we : in std_logic; 52 | lp_n : in std_logic; 53 | 54 | aRegisters: in unsigned(5 downto 0); 55 | diRegisters: in unsigned(7 downto 0); 56 | 57 | di: in unsigned(7 downto 0); 58 | diColor: in unsigned(3 downto 0); 59 | do: out unsigned(7 downto 0); 60 | 61 | vicAddr: out unsigned(13 downto 0); 62 | irq_n: out std_logic; 63 | 64 | -- Video output 65 | hSync : out std_logic; 66 | vSync : out std_logic; 67 | hBlank: out std_logic; 68 | vBlank: out std_logic; 69 | colorIndex : out unsigned(3 downto 0); 70 | border: out std_logic; 71 | 72 | -- Debug outputs 73 | debugX : out unsigned(9 downto 0); 74 | debugY : out unsigned(8 downto 0); 75 | vicRefresh : out std_logic; 76 | addrValid : out std_logic 77 | ); 78 | end entity; 79 | 80 | -------------------------------------------------------------------------------- /rtl/io_ps2_keyboard.vhd: -------------------------------------------------------------------------------- 1 | -- ----------------------------------------------------------------------- 2 | -- 3 | -- FPGA 64 4 | -- 5 | -- A fully functional commodore 64 implementation in a single FPGA 6 | -- 7 | -- ----------------------------------------------------------------------- 8 | -- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com) 9 | -- http://www.syntiac.com/fpga64.html 10 | -- ----------------------------------------------------------------------- 11 | 12 | library IEEE; 13 | use IEEE.STD_LOGIC_1164.ALL; 14 | use IEEE.numeric_std.ALL; 15 | 16 | entity io_ps2_keyboard is 17 | port ( 18 | clk: in std_logic; 19 | kbd_clk: in std_logic; 20 | kbd_dat: in std_logic; 21 | 22 | interrupt: out std_logic; 23 | scanCode: out unsigned(7 downto 0) 24 | ); 25 | end io_ps2_keyboard; 26 | 27 | architecture Behavioral of io_ps2_keyboard is 28 | signal clk_reg: std_logic; 29 | signal clk_waitNextBit: std_logic; 30 | signal clk_filter: integer range 0 to 15; 31 | signal shift_reg: unsigned(10 downto 0) := (others => '0'); 32 | 33 | signal bitsCount: integer range 0 to 10 := 0; 34 | signal timeout: integer range 0 to 5000 := 0; -- 2* 50 us at 50 Mhz 35 | begin 36 | process(clk) 37 | begin 38 | if rising_edge(clk) then 39 | -- Interrupt is edge triggered. Only 1 clock high. 40 | interrupt <= '0'; 41 | 42 | -- Timeout if keyboard does not send anymore. 43 | if timeout /= 0 then 44 | timeout <= timeout - 1; 45 | else 46 | bitsCount <= 0; 47 | end if; 48 | 49 | -- Filter glitches on the clock 50 | if (clk_reg /= kbd_clk) then 51 | clk_filter <= 15; -- Wait 15 ticks 52 | clk_reg <= kbd_clk; -- Store clock edge to detect changes 53 | clk_waitNextBit <= '0'; -- Next bit comming up... 54 | elsif (clk_filter /= 0) then 55 | -- Wait for clock to stabilise 56 | -- Clock must be stable before we sample the data line. 57 | clk_filter <= clk_filter - 1; 58 | elsif (clk_reg = '1') and (clk_waitNextBit = '0') then 59 | -- We have a stable clock, so assume stable data too. 60 | clk_waitNextBit <= '1'; 61 | 62 | -- Move data into shift register 63 | shift_reg <= kbd_dat & shift_reg(10 downto 1); 64 | timeout <= 5000; 65 | if bitsCount < 10 then 66 | bitsCount <= bitsCount + 1; 67 | else 68 | -- 10 bits received. Output new scancode 69 | bitsCount <= 0; 70 | interrupt <= '1'; 71 | scanCode <= shift_reg(9 downto 2); 72 | end if; 73 | end if; 74 | end if; 75 | end process; 76 | 77 | end Behavioral; 78 | -------------------------------------------------------------------------------- /rtl/cpu_6510.vhd: -------------------------------------------------------------------------------- 1 | -- ----------------------------------------------------------------------- 2 | -- 3 | -- FPGA 64 4 | -- 5 | -- A fully functional commodore 64 implementation in a single FPGA 6 | -- 7 | -- ----------------------------------------------------------------------- 8 | -- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com) 9 | -- http://www.syntiac.com/fpga64.html 10 | -- ----------------------------------------------------------------------- 11 | -- 12 | -- 6510 wrapper for 65xx core 13 | -- Adds 8 bit I/O port mapped at addresses $0000 to $0001 14 | -- 15 | -- ----------------------------------------------------------------------- 16 | 17 | library IEEE; 18 | use ieee.std_logic_1164.ALL; 19 | use ieee.numeric_std.ALL; 20 | 21 | -- ----------------------------------------------------------------------- 22 | 23 | entity cpu_6510 is 24 | port ( 25 | clk : in std_logic; 26 | enable : in std_logic; 27 | reset : in std_logic; 28 | nmi_n : in std_logic; 29 | nmi_ack : out std_logic; 30 | irq_n : in std_logic; 31 | rdy : in std_logic; 32 | 33 | di : in unsigned(7 downto 0); 34 | do : out unsigned(7 downto 0); 35 | addr : out unsigned(15 downto 0); 36 | we : out std_logic; 37 | 38 | diIO : in unsigned(7 downto 0); 39 | doIO : out unsigned(7 downto 0) 40 | ); 41 | end cpu_6510; 42 | 43 | -- ----------------------------------------------------------------------- 44 | 45 | architecture rtl of cpu_6510 is 46 | signal localA : std_logic_vector(23 downto 0); 47 | signal localDi : std_logic_vector(7 downto 0); 48 | signal localDo : std_logic_vector(7 downto 0); 49 | signal localWe : std_logic; 50 | 51 | signal currentIO : std_logic_vector(7 downto 0); 52 | signal ioDir : std_logic_vector(7 downto 0); 53 | signal ioData : std_logic_vector(7 downto 0); 54 | 55 | signal accessIO : std_logic; 56 | begin 57 | 58 | cpu: work.T65 59 | port map( 60 | Mode => "00", 61 | Res_n => not reset, 62 | Enable => enable, 63 | Clk => clk, 64 | Rdy => rdy, 65 | Abort_n => '1', 66 | IRQ_n => irq_n, 67 | NMI_n => nmi_n, 68 | SO_n => '1', 69 | R_W_n => localWe, 70 | A => localA, 71 | DI => localDi, 72 | DO => localDo, 73 | NMI_ack => nmi_ack 74 | ); 75 | 76 | accessIO <= '1' when localA(15 downto 1) = X"000"&"000" else '0'; 77 | localDi <= localDo when localWe = '0' else std_logic_vector(di) when accessIO = '0' else ioDir when localA(0) = '0' else currentIO; 78 | 79 | process(clk) 80 | begin 81 | if rising_edge(clk) then 82 | if accessIO = '1' then 83 | if localWe = '0' and enable = '1' then 84 | if localA(0) = '0' then 85 | ioDir <= localDo; 86 | else 87 | ioData <= localDo; 88 | end if; 89 | end if; 90 | end if; 91 | if reset = '1' then 92 | ioDir <= (others => '0'); 93 | end if; 94 | end if; 95 | end process; 96 | 97 | process(clk) 98 | begin 99 | if rising_edge(clk) then 100 | for i in 0 to 7 loop 101 | if ioDir(i) = '0' then 102 | currentIO(i) <= std_logic(diIO(i)); 103 | else 104 | currentIO(i) <= ioData(i); 105 | end if; 106 | end loop; 107 | end if; 108 | end process; 109 | 110 | -- Cunnect zee wires 111 | addr <= unsigned(localA(15 downto 0)); 112 | do <= unsigned(localDo); 113 | we <= not localWe; 114 | doIO <= unsigned(currentIO); 115 | end architecture; 116 | -------------------------------------------------------------------------------- /rtl/sid/oscillator.vhd: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | -- 3 | -- (C) COPYRIGHT 2010 Gideon's Logic Architectures' 4 | -- 5 | ------------------------------------------------------------------------------- 6 | -- 7 | -- Author: Gideon Zweijtzer (gideon.zweijtzer (at) gmail.com) 8 | -- 9 | -- Note that this file is copyrighted, and is not supposed to be used in other 10 | -- projects without written permission from the author. 11 | -- 12 | ------------------------------------------------------------------------------- 13 | library ieee; 14 | use ieee.std_logic_1164.all; 15 | use ieee.numeric_std.all; 16 | 17 | entity oscillator is 18 | generic ( 19 | g_num_voices : integer := 8); 20 | port ( 21 | clock : in std_logic; 22 | reset : in std_logic; 23 | 24 | enable_i : in std_logic; 25 | voice_i : in unsigned(3 downto 0); 26 | freq : in unsigned(15 downto 0); 27 | test : in std_logic := '0'; 28 | sync : in std_logic := '0'; 29 | 30 | voice_o : out unsigned(3 downto 0); 31 | enable_o : out std_logic; 32 | test_o : out std_logic; 33 | osc_val : out unsigned(23 downto 0); 34 | carry_20 : out std_logic; 35 | msb_other: out std_logic ); 36 | 37 | end oscillator; 38 | 39 | 40 | architecture Gideon of oscillator is 41 | type accu_array_t is array (natural range <>) of unsigned(23 downto 0); 42 | signal accu_reg : accu_array_t(0 to g_num_voices-1) := (others => (others => '0')); 43 | 44 | type int4_array is array (natural range <>) of integer range 0 to 15; 45 | 46 | constant voice_linkage : int4_array(0 to 15) := ( 2, 0, 1, 7, 3, 4, 5, 6, 47 | 10, 8, 9, 15, 11, 12, 13, 14 ); 48 | 49 | signal ring_index : integer range 0 to 15; 50 | signal sync_index : integer range 0 to 15; 51 | signal msb_register : std_logic_vector(0 to 15) := (others => '0'); 52 | signal car_register : std_logic_vector(0 to 15) := (others => '0'); 53 | signal do_sync : std_logic; 54 | begin 55 | sync_index <= voice_linkage(to_integer(voice_i)); 56 | do_sync <= sync and car_register(sync_index); 57 | ring_index <= voice_linkage(to_integer(voice_i)); 58 | 59 | process(clock) 60 | variable cur_accu : unsigned(23 downto 0); 61 | variable new_accu : unsigned(24 downto 0); 62 | variable cur_20 : std_logic; 63 | begin 64 | if rising_edge(clock) then 65 | cur_accu := accu_reg(0); 66 | cur_20 := cur_accu(20); 67 | 68 | if reset='1' or test='1' or do_sync='1' then 69 | new_accu := (others => '0'); 70 | else 71 | new_accu := ('0' & cur_accu) + freq; 72 | end if; 73 | 74 | osc_val <= new_accu(23 downto 0); 75 | -- carry <= new_accu(24); 76 | carry_20 <= new_accu(20) xor cur_20; 77 | msb_other <= msb_register(ring_index); 78 | voice_o <= voice_i; 79 | enable_o <= enable_i; 80 | test_o <= test; 81 | 82 | if enable_i='1' then 83 | accu_reg(0 to g_num_voices-2) <= accu_reg(1 to g_num_voices-1); 84 | accu_reg(g_num_voices-1) <= new_accu(23 downto 0); 85 | 86 | car_register(to_integer(voice_i)) <= new_accu(24); 87 | msb_register(to_integer(voice_i)) <= cur_accu(23); 88 | end if; 89 | end if; 90 | end process; 91 | 92 | end Gideon; 93 | -------------------------------------------------------------------------------- /rtl/sid/sid_mixer.vhd: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | -- 3 | -- (C) COPYRIGHT 2010 Gideon's Logic Architectures' 4 | -- 5 | ------------------------------------------------------------------------------- 6 | -- 7 | -- Author: Gideon Zweijtzer (gideon.zweijtzer (at) gmail.com) 8 | -- 9 | -- Note that this file is copyrighted, and is not supposed to be used in other 10 | -- projects without written permission from the author. 11 | -- 12 | ------------------------------------------------------------------------------- 13 | library ieee; 14 | use ieee.std_logic_1164.all; 15 | use ieee.numeric_std.all; 16 | 17 | library work; 18 | use work.my_math_pkg.all; 19 | 20 | entity sid_mixer is 21 | port ( 22 | clock : in std_logic; 23 | reset : in std_logic; 24 | 25 | valid_in : in std_logic := '0'; 26 | 27 | direct_out : in signed(17 downto 0); 28 | high_pass : in signed(17 downto 0); 29 | band_pass : in signed(17 downto 0); 30 | low_pass : in signed(17 downto 0); 31 | 32 | filter_hp : in std_logic; 33 | filter_bp : in std_logic; 34 | filter_lp : in std_logic; 35 | 36 | volume : in unsigned(3 downto 0); 37 | 38 | mixed_out : out signed(17 downto 0); 39 | valid_out : out std_logic ); 40 | end sid_mixer; 41 | 42 | architecture arith of sid_mixer is 43 | signal mix_i : signed(17 downto 0); 44 | signal mix_uns : unsigned(16 downto 0); 45 | signal vol_uns : unsigned(16 downto 0); 46 | signal vol_s : signed(16 downto 0); 47 | signal state : integer range 0 to 7; 48 | signal p_mul : unsigned(33 downto 0); 49 | signal p_mul_s : signed(34 downto 0); 50 | 51 | type t_volume_lut is array(natural range <>) of unsigned(15 downto 0); 52 | constant c_volume_lut : t_volume_lut(0 to 15) := ( 53 | X"0000", X"0EEF", X"1DDE", X"2CCD", X"3BBC", X"4AAA", X"5999", X"6888", 54 | X"7777", X"8666", X"9555", X"A444", X"B333", X"C221", X"D110", X"DFFF" ); 55 | 56 | 57 | begin 58 | process(clock) 59 | variable mix_total : signed(17 downto 0); 60 | begin 61 | if rising_edge(clock) then 62 | valid_out <= '0'; 63 | 64 | state <= state + 1; 65 | case state is 66 | when 0 => 67 | if valid_in = '1' then 68 | mix_i <= sum_limit(direct_out, to_signed(16384, 18)); 69 | else 70 | state <= 0; 71 | end if; 72 | 73 | when 1 => 74 | if filter_hp='1' then 75 | mix_i <= sum_limit(mix_i, high_pass); 76 | end if; 77 | 78 | when 2 => 79 | if filter_bp='1' then 80 | mix_i <= sum_limit(mix_i, band_pass); 81 | end if; 82 | 83 | when 3 => 84 | if filter_lp='1' then 85 | mix_i <= sum_limit(mix_i, low_pass); 86 | end if; 87 | 88 | when 4 => 89 | -- p_mul <= mix_uns * vol_uns; 90 | p_mul_s <= mix_i * vol_s; 91 | valid_out <= '1'; 92 | state <= 0; 93 | 94 | when others => 95 | state <= 0; 96 | 97 | end case; 98 | 99 | -- mix_total := not(p_mul(32)) & signed(p_mul(31 downto 15)); 100 | -- mixed_out <= mix_total; -- + to_signed(16384, 18); 101 | mixed_out <= p_mul_s(33 downto 16); 102 | 103 | if reset='1' then 104 | mix_i <= (others => '0'); 105 | state <= 0; 106 | end if; 107 | end if; 108 | end process; 109 | 110 | -- vol_uns <= "0" & volume & volume & volume & volume; 111 | -- vol_uns <= '0' & c_volume_lut(to_integer(volume)); 112 | -- mix_uns <= not mix_i(17) & unsigned(mix_i(16 downto 1)); 113 | 114 | vol_s <= '0' & signed(c_volume_lut(to_integer(volume))); 115 | end arith; 116 | -------------------------------------------------------------------------------- /rtl/fpga64.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) tap_fifo.vhd] 2 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) c1530.vhd] 3 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) progressbar.v] 4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sid8580/sid_voice.v] 5 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sid8580/sid_filters.v] 6 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sid8580/sid_envelope.v] 7 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sid8580/sid8580.v] 8 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) fpga64_sid_iec.vhd] 9 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) video_vicII_656x_e.vhd] 10 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) video_vicII_656x_a.vhd] 11 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) fpga64_rgbcolor.vhd] 12 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) fpga64_keyboard_matrix_mark_mcdougall.vhd] 13 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) fpga64_buslogic_roms_mmu.vhd] 14 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mos6526.v] 15 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) mos6526.vhd] 16 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) cpu_6510.vhd] 17 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) reu.vhd] 18 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) cartridge.v] 19 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) c64_midi.vhd] 20 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) gen_uart.v] 21 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) rom_c64_chargen.vhd] 22 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) io_ps2_keyboard.vhd] 23 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) gen_ram.vhd] 24 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) sid/wave_map.vhd] 25 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) sid/sid_top.vhd] 26 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) sid/sid_regs.vhd] 27 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) sid/sid_mixer.vhd] 28 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) sid/sid_filter.vhd] 29 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) sid/sid_debug_pkg.vhd] 30 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) sid/sid_ctrl.vhd] 31 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) sid/Q_table.vhd] 32 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) sid/oscillator.vhd] 33 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) sid/my_math_pkg.vhd] 34 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) sid/mult_acc.vhd] 35 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) sid/adsr_multi.vhd] 36 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) c1541/via6522.vhd] 37 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) c1541/spram.vhd] 38 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) c1541/spi_controller.vhd] 39 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) c1541/mist_sd_card.sv] 40 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) c1541/gen_rom.vhd] 41 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) c1541/gcr_floppy.vhd] 42 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) c1541/c1541_sd.vhd] 43 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) c1541/c1541_logic.vhd] 44 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) mist/c64_mist_top.sv] 45 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) mist/c64_mist.vhd] 46 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mist/sigma_delta_dac.v] 47 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mist/sdram.v] 48 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) T65/T65.qip] 49 | -------------------------------------------------------------------------------- /C64_mist.sdc: -------------------------------------------------------------------------------- 1 | #************************************************************ 2 | # THIS IS A WIZARD-GENERATED FILE. 3 | # 4 | # Version 13.1.4 Build 182 03/12/2014 SJ Full Version 5 | # 6 | #************************************************************ 7 | 8 | # Copyright (C) 1991-2014 Altera Corporation 9 | # Your use of Altera Corporation's design tools, logic functions 10 | # and other software and tools, and its AMPP partner logic 11 | # functions, and any output files from any of the foregoing 12 | # (including device programming or simulation files), and any 13 | # associated documentation or information are expressly subject 14 | # to the terms and conditions of the Altera Program License 15 | # Subscription Agreement, Altera MegaCore Function License 16 | # Agreement, or other applicable license agreement, including, 17 | # without limitation, that your use is for the sole purpose of 18 | # programming logic devices manufactured by Altera and sold by 19 | # Altera or its authorized distributors. Please refer to the 20 | # applicable agreement for further details. 21 | 22 | 23 | 24 | # Clock constraints 25 | 26 | create_clock -name "CLOCK_27" -period 37.037 [get_ports {CLOCK_27}] 27 | create_clock -name {SPI_SCK} -period 41.666 -waveform { 20.8 41.666 } [get_ports {SPI_SCK}] 28 | 29 | # Automatically constrain PLL and other generated clocks 30 | derive_pll_clocks -create_base_clocks 31 | 32 | # Automatically calculate clock uncertainty to jitter and other effects. 33 | derive_clock_uncertainty 34 | 35 | # SPI ports 36 | set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DI}] 37 | set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SCK}] 38 | set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS2}] 39 | set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS3}] 40 | set_output_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DO}] 41 | 42 | # Clock groups 43 | set_clock_groups -asynchronous -group [get_clocks {SPI_SCK}] -group [get_clocks {c64_mist|pll|altpll_component|auto_generated|pll1|clk[*]}] 44 | set_clock_groups -asynchronous -group [get_clocks {SPI_SCK}] -group [get_clocks {c64_mist|pll_2|altpll_component|auto_generated|pll1|clk[*]}] 45 | set_clock_groups -asynchronous -group [get_clocks {c64_mist|pll_2|altpll_component|auto_generated|pll1|clk[0]}] -group [get_clocks {c64_mist|pll|altpll_component|auto_generated|pll1|clk[*]}] 46 | 47 | 48 | # Some relaxed constrain to the VGA pins. The signals should arrive together, the delay is not really important. 49 | set_output_delay -clock [get_clocks {c64_mist|pll|altpll_component|auto_generated|pll1|clk[1]}] -max 0 [get_ports {VGA_*}] 50 | set_output_delay -clock [get_clocks {c64_mist|pll|altpll_component|auto_generated|pll1|clk[1]}] -min -5 [get_ports {VGA_*}] 51 | 52 | # SDRAM delays 53 | set_input_delay -clock [get_clocks {c64_mist|pll|altpll_component|auto_generated|pll1|clk[0]}] -reference_pin [get_ports {SDRAM_CLK}] -max 6.4 [get_ports SDRAM_DQ[*]] 54 | set_input_delay -clock [get_clocks {c64_mist|pll|altpll_component|auto_generated|pll1|clk[0]}] -reference_pin [get_ports {SDRAM_CLK}] -min 3.2 [get_ports SDRAM_DQ[*]] 55 | 56 | set_output_delay -clock [get_clocks {c64_mist|pll|altpll_component|auto_generated|pll1|clk[0]}] -reference_pin [get_ports {SDRAM_CLK}] -max 1.5 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] 57 | set_output_delay -clock [get_clocks {c64_mist|pll|altpll_component|auto_generated|pll1|clk[0]}] -reference_pin [get_ports {SDRAM_CLK}] -min -0.8 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] 58 | 59 | set_multicycle_path -from [get_clocks {c64_mist|pll|altpll_component|auto_generated|pll1|clk[0]}] -to [get_clocks {c64_mist|pll|altpll_component|auto_generated|pll1|clk[2]}] -setup 2 60 | 61 | set_multicycle_path -from [get_clocks {c64_mist|pll|altpll_component|auto_generated|pll1|clk[0]}] -to [get_clocks {c64_mist|pll|altpll_component|auto_generated|pll1|clk[2]}] -hold 2 62 | 63 | set_multicycle_path -to {VGA_*[*]} -setup 2 64 | set_multicycle_path -to {VGA_*[*]} -hold 1 65 | 66 | set_false_path -to [get_ports {SDRAM_CLK}] 67 | set_false_path -from [get_ports {UART_RX}] 68 | set_false_path -to [get_ports {UART_TX}] 69 | set_false_path -to [get_ports {AUDIO_L}] 70 | set_false_path -to [get_ports {AUDIO_R}] 71 | set_false_path -to [get_ports {LED}] 72 | -------------------------------------------------------------------------------- /rtl/c64_midi.vhd: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------- 2 | -- c64_midi.vhd - 6850 ACIA based MIDI interface 3 | -- 2022 - Slingshot 4 | -- 5 | -- https://codebase64.org/doku.php?id=base:c64_midi_interfaces 6 | -- Mode 1 : SEQUENTIAL CIRCUITS INC. 7 | -- Mode 2 : PASSPORT & SENTECH 8 | -- Mode 3 : DATEL/SIEL/JMS/C-LAB 9 | -- Mode 4 : NAMESOFT 10 | --------------------------------------------------------------------------------- 11 | 12 | library ieee; 13 | use ieee.std_logic_1164.all; 14 | use ieee.std_logic_unsigned.all; 15 | use ieee.numeric_std.all; 16 | 17 | entity c64_midi is 18 | port( 19 | clk32 : in std_logic; 20 | reset : in std_logic; 21 | Mode : in std_logic_vector( 2 downto 0); 22 | E : in std_logic; 23 | IOE : in std_logic; 24 | A : in std_logic_vector(15 downto 0); 25 | Din : in std_logic_vector( 7 downto 0); 26 | Dout : out std_logic_vector( 7 downto 0); 27 | OE : out std_logic; 28 | RnW : in std_logic; 29 | nIRQ : out std_logic; 30 | nNMI : out std_logic; 31 | 32 | RX : in std_logic; 33 | TX : out std_logic 34 | ); 35 | end c64_midi; 36 | 37 | architecture rtl of c64_midi is 38 | 39 | component gen_uart_mc_6850 is 40 | port ( 41 | reset : in std_logic; 42 | clk : in std_logic; 43 | rx_clk_en : in std_logic; 44 | tx_clk_en : in std_logic; 45 | din : in std_logic_vector(7 downto 0); 46 | dout : out std_logic_vector(7 downto 0); 47 | rnw : in std_logic; 48 | cs : in std_logic; 49 | rs : in std_logic; 50 | irq_n : out std_logic; 51 | cts_n : in std_logic; 52 | dcd_n : in std_logic; 53 | rts_n : out std_logic; 54 | rx : in std_logic; 55 | tx : out std_logic 56 | ); 57 | end component; 58 | 59 | signal acia_sel : std_logic; 60 | signal acia_rs : std_logic; 61 | signal acia_rw : std_logic; 62 | signal acia_irq_n : std_logic; 63 | signal acia_rxtxclk_sel : std_logic; 64 | signal acia_clk_en : std_logic; 65 | signal acia_clk_en_cnt : unsigned(5 downto 0); 66 | signal acia_din : std_logic_vector(7 downto 0); 67 | begin 68 | 69 | process(clk32) begin 70 | if rising_edge(clk32) then 71 | acia_din <= Din; 72 | if reset = '1' then 73 | acia_clk_en <= '0'; 74 | acia_clk_en_cnt <= (others=>'0'); 75 | else 76 | acia_clk_en <= '0'; 77 | acia_clk_en_cnt <= acia_clk_en_cnt + 1; 78 | -- 2 MHz or 512 kHz 79 | if acia_clk_en_cnt = 0 or (acia_rxtxclk_sel = '1' and acia_clk_en_cnt(3 downto 0) = 0) then 80 | acia_clk_en <= '1'; 81 | end if; 82 | end if; 83 | end if; 84 | end process; 85 | 86 | process(Mode, IOE, A, RnW, acia_irq_n) begin 87 | acia_rxtxclk_sel <= '0'; 88 | acia_sel <= '0'; 89 | acia_rw <= '1'; 90 | acia_rs <= '0'; 91 | nIRQ <= '1'; 92 | nNMI <= '1'; 93 | case Mode is 94 | when "001" => 95 | -- Mode 1 : SEQUENTIAL CIRCUITS INC. 96 | nIRQ <= acia_irq_n; 97 | acia_sel <= IOE and not A(2) and not A(3) and not A(4); 98 | acia_rs <= A(0); 99 | acia_rw <= A(1); 100 | when "010" => 101 | -- Mode 2 : PASSPORT & SENTECH 102 | nIRQ <= acia_irq_n; 103 | acia_sel <= IOE and not A(2) and A(3) and not A(4); 104 | acia_rs <= A(0); 105 | acia_rw <= RnW; 106 | when "011" => 107 | -- Mode 3 : DATEL/SIEL/JMS/C-LAB 108 | acia_rxtxclk_sel <= '1'; -- for 2 MHz RX/TX clock 109 | nIRQ <= acia_irq_n; 110 | acia_sel <= IOE and A(2) and not A(3) and not A(4); 111 | acia_rs <= A(0); 112 | acia_rw <= A(1); 113 | when "100" => 114 | -- Mode 4 : NAMESOFT 115 | nNMI <= acia_irq_n; 116 | acia_sel <= IOE and not A(2) and not A(3) and not A(4); 117 | acia_rs <= A(0); 118 | acia_rw <= A(1); 119 | when others => null; 120 | end case; 121 | end process; 122 | 123 | OE <= acia_sel and acia_rw; 124 | 125 | acia_inst : gen_uart_mc_6850 126 | port map ( 127 | reset => reset, 128 | clk => clk32, 129 | rx_clk_en => acia_clk_en, 130 | tx_clk_en => acia_clk_en, 131 | din => acia_din, 132 | dout => Dout, 133 | rnw => acia_rw, 134 | cs => acia_sel, 135 | rs => acia_rs, 136 | irq_n => acia_irq_n, 137 | cts_n => '0', 138 | dcd_n => '0', 139 | rts_n => open, 140 | rx => RX, 141 | tx => TX 142 | ); 143 | 144 | end rtl; 145 | -------------------------------------------------------------------------------- /rtl/sid/my_math_pkg.vhd: -------------------------------------------------------------------------------- 1 | library ieee; 2 | use ieee.std_logic_1164.all; 3 | use ieee.numeric_std.all; 4 | 5 | package my_math_pkg is 6 | 7 | function sum_limit(i1, i2 : signed) return signed; 8 | function sub_limit(i1, i2 : signed) return signed; 9 | function sum_limit(i1, i2 : unsigned) return unsigned; 10 | function extend(x : signed; len : natural) return signed; 11 | function extend(x : unsigned; len : natural) return unsigned; 12 | function left_align(x : signed; len : natural) return signed; 13 | function left_scale(x : signed; sh : natural) return signed; 14 | 15 | -- function shift_right(x : signed; positions: natural) return signed; 16 | end; 17 | 18 | package body my_math_pkg is 19 | 20 | function sum_limit(i1, i2 : signed) return signed is 21 | variable o : signed(i1'range); 22 | begin 23 | assert i1'length = i2'length 24 | report "i1 and i2 should have the same length!" 25 | severity failure; 26 | o := i1 + i2; 27 | if (i1(i1'left) = i2(i2'left)) and (o(o'left) /= i1(i1'left)) then 28 | if i1(i1'left)='1' then 29 | o := to_signed(-(2**(o'length-1)), o'length); 30 | else 31 | o := to_signed(2**(o'length-1) - 1, o'length); 32 | end if; 33 | end if; 34 | return o; 35 | end function; 36 | 37 | function sub_limit(i1, i2 : signed) return signed is 38 | variable o : signed(i1'range); 39 | begin 40 | assert i1'length = i2'length 41 | report "i1 and i2 should have the same length!" 42 | severity failure; 43 | o := i1 - i2; 44 | if (i1(i1'left) /= i2(i2'left)) and (o(o'left) /= i1(i1'left)) then 45 | if i1(i1'left)='1' then 46 | o := to_signed(-(2**(o'length-1)), o'length); 47 | else 48 | o := to_signed(2**(o'length-1) - 1, o'length); 49 | end if; 50 | end if; 51 | return o; 52 | end function; 53 | 54 | function sum_limit(i1, i2 : unsigned) return unsigned is 55 | variable o : unsigned(i1'length downto 0); 56 | begin 57 | o := ('0' & i1) + i2; 58 | if o(o'left)='1' then 59 | o := (others => '1'); 60 | end if; 61 | return o(i1'length-1 downto 0); 62 | end function; 63 | 64 | function extend(x : signed; len : natural) return signed is 65 | variable ret : signed(len-1 downto 0); 66 | alias a : signed(x'length-1 downto 0) is x; 67 | begin 68 | ret := (others => x(x'left)); 69 | ret(a'range) := a; 70 | return ret; 71 | end function extend; 72 | 73 | function extend(x : unsigned; len : natural) return unsigned is 74 | variable ret : unsigned(len-1 downto 0); 75 | alias a : unsigned(x'length-1 downto 0) is x; 76 | begin 77 | ret := (others => '0'); 78 | ret(a'range) := a; 79 | return ret; 80 | end function extend; 81 | 82 | function left_align(x : signed; len : natural) return signed is 83 | variable ret : signed(len-1 downto 0); 84 | begin 85 | ret := (others => '0'); 86 | ret(len-1 downto len-x'length) := x; 87 | return ret; 88 | end function left_align; 89 | 90 | function left_scale(x : signed; sh : natural) return signed is 91 | alias a : signed(x'length-1 downto 0) is x; 92 | variable ret : signed(x'length-(1+sh) downto 0); 93 | variable top : signed(sh downto 0); 94 | begin 95 | if sh=0 then 96 | return x; 97 | end if; 98 | 99 | top := a(a'high downto a'high-sh); 100 | if (top = -1) or (top = 0) then -- can shift without getting punished! 101 | ret := a(ret'range); 102 | elsif a(a'high)='1' then -- negative and can't shift, so max neg: 103 | ret := (others => '0'); 104 | ret(ret'high) := '1'; 105 | else -- positive and can't shift, so max pos 106 | ret := (others => '1'); 107 | ret(ret'high) := '0'; 108 | end if; 109 | return ret; 110 | end function left_scale; 111 | 112 | -- function shift_right(x : signed; positions: natural) return signed is 113 | -- alias a : signed(x'length-1 downto 0) is x; 114 | -- variable ret : signed(x'length-1 downto 0); 115 | -- begin 116 | -- ret := (others => x(x'left)); 117 | -- ret(a'left-positions downto 0) := a(a'left downto positions); 118 | -- return ret; 119 | -- end function shift_right; 120 | end; 121 | -------------------------------------------------------------------------------- /rtl/sid8580/sid_filters.v: -------------------------------------------------------------------------------- 1 | module sid_filters (clk, rst, Fc_lo, Fc_hi, Res_Filt, Mode_Vol, 2 | voice1, voice2, voice3, input_valid, ext_in, sound, extfilter_en); 3 | 4 | // Input Signals 5 | input wire [ 0:0] clk; 6 | input wire [ 0:0] rst; 7 | input wire [ 7:0] Fc_lo; 8 | input wire [ 7:0] Fc_hi; 9 | input wire [ 7:0] Res_Filt; 10 | input wire [ 7:0] Mode_Vol; 11 | input wire [11:0] voice1; 12 | input wire [11:0] voice2; 13 | input wire [11:0] voice3; 14 | input wire [ 0:0] input_valid; 15 | input wire [11:0] ext_in; 16 | input wire [ 0:0] extfilter_en; 17 | 18 | // Output Signals 19 | output reg [15:0] sound; 20 | 21 | // Internal Signals 22 | reg signed [17:0] mula; 23 | reg signed [17:0] mulb; 24 | reg [35:0] mulr; 25 | reg [ 0:0] mulen; 26 | 27 | wire [35:0] mul1; 28 | wire [35:0] mul2; 29 | wire [35:0] mul3; 30 | wire [35:0] mul4; 31 | 32 | wire [10:0] divmul [0:15]; 33 | 34 | reg signed [17:0] Vhp; 35 | reg signed [17:0] Vbp; 36 | reg [17:0] dVbp; 37 | reg [17:0] Vlp; 38 | reg [17:0] dVlp; 39 | reg [17:0] Vi; 40 | reg [17:0] Vnf; 41 | reg [17:0] Vf; 42 | reg signed [17:0] w0; 43 | reg signed [17:0] q; 44 | reg [ 3:0] state; 45 | 46 | assign divmul[4'h0] = 11'd1448; 47 | assign divmul[4'h1] = 11'd1328; 48 | assign divmul[4'h2] = 11'd1218; 49 | assign divmul[4'h3] = 11'd1117; 50 | assign divmul[4'h4] = 11'd1024; 51 | assign divmul[4'h5] = 11'd939; 52 | assign divmul[4'h6] = 11'd861; 53 | assign divmul[4'h7] = 11'd790; 54 | assign divmul[4'h8] = 11'd724; 55 | assign divmul[4'h9] = 11'd664; 56 | assign divmul[4'ha] = 11'd609; 57 | assign divmul[4'hb] = 11'd558; 58 | assign divmul[4'hc] = 11'd512; 59 | assign divmul[4'hd] = 11'd470; 60 | assign divmul[4'he] = 11'd431; 61 | assign divmul[4'hf] = 11'd395; 62 | 63 | // Multiplier 64 | always @(posedge clk) 65 | begin 66 | if (mulen) 67 | mulr <= mula * mulb; 68 | end 69 | 70 | assign mul1 = w0 * Vhp; 71 | assign mul2 = w0 * Vbp; 72 | assign mul3 = q * Vbp; 73 | assign mul4 = 18'd82355 * ({Fc_hi, Fc_lo[2:0]} + 1'b1); 74 | 75 | // Filter 76 | always @(posedge clk) 77 | begin 78 | if (rst) 79 | begin 80 | state <= 4'h0; 81 | Vlp <= 18'h00000; 82 | Vbp <= 18'h00000; 83 | Vhp <= 18'h00000; 84 | end 85 | else 86 | begin 87 | mula <= 18'h00000; 88 | mulb <= 18'h00000; 89 | mulen <= 1'b0; 90 | case (state) 91 | 4'h0: 92 | begin 93 | if (input_valid) 94 | begin 95 | state <= 4'h1; 96 | Vi <= 18'h00000; 97 | Vnf <= 18'h00000; 98 | end 99 | end 100 | 4'h1: 101 | begin 102 | state <= 4'h2; 103 | w0 <= {mul4[35], mul4[28:12]}; 104 | if (Res_Filt[0]) 105 | Vi <= Vi + (voice1 << 2); 106 | else 107 | Vnf <= Vnf + (voice1 << 2); 108 | end 109 | 4'h2: 110 | begin 111 | state <= 4'h3; 112 | if (Res_Filt[1]) 113 | Vi <= Vi + (voice2 << 2); 114 | else 115 | Vnf <= Vnf + (voice2 << 2); 116 | end 117 | 4'h3: 118 | begin 119 | state <= 4'h4; 120 | if (Res_Filt[2]) 121 | Vi <= Vi + (voice3 << 2); 122 | else 123 | if (!Mode_Vol[7]) 124 | Vnf <= Vnf + (voice3 << 2); 125 | dVbp <= {mul1[35], mul1[35:19]}; 126 | end 127 | 4'h4: 128 | begin 129 | state <= 4'h5; 130 | if (Res_Filt[3]) 131 | Vi <= Vi + (ext_in << 2); 132 | else 133 | Vnf <= Vnf + (ext_in << 2); 134 | dVlp <= {mul2[35], mul2[35:19]}; 135 | Vbp <= Vbp - dVbp; 136 | q <= divmul[Res_Filt[7:4]]; 137 | end 138 | 4'h5: 139 | begin 140 | state <= 4'h6; 141 | Vlp <= Vlp - dVlp; 142 | Vf <= (Mode_Vol[5]) ? Vbp : 18'h00000; 143 | end 144 | 4'h6: 145 | begin 146 | state <= 4'h7; 147 | Vhp <= {mul3[35], mul3[26:10]} - Vlp; 148 | Vf <= (Mode_Vol[4]) ? Vf + Vlp : Vf; 149 | end 150 | 4'h7: 151 | begin 152 | state <= 4'h8; 153 | Vhp <= Vhp - Vi; 154 | end 155 | 4'h8: 156 | begin 157 | state <= 4'h9; 158 | Vf <= (Mode_Vol[6]) ? Vf + Vhp : Vf; 159 | end 160 | 4'h9: 161 | begin 162 | state <= 4'ha; 163 | //Vf <= {~Vf + 1'b1} + Vnf; 164 | Vf <= (extfilter_en) ? {~Vf + 1'b1} + Vnf : Vi + Vnf; 165 | end 166 | 4'ha: 167 | begin 168 | state <= 4'hb; 169 | mulen <= 1'b1; 170 | mula <= Vf; 171 | mulb <= Mode_Vol[3:0]; 172 | end 173 | 4'hb: 174 | begin 175 | state <= 4'h0; 176 | sound <= (mulr[21] != mulr[20]) ? sound : mulr[20:5]; 177 | end 178 | default: 179 | ; 180 | endcase 181 | end 182 | end 183 | 184 | endmodule 185 | -------------------------------------------------------------------------------- /rtl/mist/cyc3/pll_c64_ntsc.mif: -------------------------------------------------------------------------------- 1 | -- Copyright (C) 1991-2014 Altera Corporation 2 | -- Your use of Altera Corporation's design tools, logic functions 3 | -- and other software and tools, and its AMPP partner logic 4 | -- functions, and any output files from any of the foregoing 5 | -- (including device programming or simulation files), and any 6 | -- associated documentation or information are expressly subject 7 | -- to the terms and conditions of the Altera Program License 8 | -- Subscription Agreement, Altera MegaCore Function License 9 | -- Agreement, or other applicable license agreement, including, 10 | -- without limitation, that your use is for the sole purpose of 11 | -- programming logic devices manufactured by Altera and sold by 12 | -- Altera or its authorized distributors. Please refer to the 13 | -- applicable agreement for further details. 14 | 15 | -- MIF file representing initial state of PLL Scan Chain 16 | -- Device Family: Cyclone III 17 | -- Device Part: - 18 | -- Device Speed Grade: 8 19 | -- PLL Scan Chain: Fast PLL (144 bits) 20 | -- File Name: /home/gyuri/git/c64/rtl/mist/cyc3/pll_c64_ntsc.mif 21 | -- Generated: Mon Apr 15 23:13:05 2024 22 | 23 | WIDTH=1; 24 | DEPTH=144; 25 | 26 | ADDRESS_RADIX=UNS; 27 | DATA_RADIX=UNS; 28 | 29 | CONTENT BEGIN 30 | 0 : 0; -- Reserved Bits = 0 (1 bit(s)) 31 | 1 : 0; -- Reserved Bits = 0 (1 bit(s)) 32 | 2 : 0; -- Loop Filter Capacitance = 0 (2 bit(s)) (Setting 0) 33 | 3 : 0; 34 | 4 : 0; -- Loop Filter Resistance = 8 (5 bit(s)) (Setting 8) 35 | 5 : 1; 36 | 6 : 0; 37 | 7 : 0; 38 | 8 : 0; 39 | 9 : 0; -- VCO Post Scale = 0 (1 bit(s)) (VCO post-scale divider counter value = 2) 40 | 10 : 0; -- Reserved Bits = 0 (5 bit(s)) 41 | 11 : 0; 42 | 12 : 0; 43 | 13 : 0; 44 | 14 : 0; 45 | 15 : 0; -- Charge Pump Current = 1 (3 bit(s)) (Setting 1) 46 | 16 : 0; 47 | 17 : 1; 48 | 18 : 0; -- N counter: Bypass = 0 (1 bit(s)) 49 | 19 : 0; -- N counter: High Count = 3 (8 bit(s)) 50 | 20 : 0; 51 | 21 : 0; 52 | 22 : 0; 53 | 23 : 0; 54 | 24 : 0; 55 | 25 : 1; 56 | 26 : 1; 57 | 27 : 1; -- N counter: Odd Division = 1 (1 bit(s)) 58 | 28 : 0; -- N counter: Low Count = 2 (8 bit(s)) 59 | 29 : 0; 60 | 30 : 0; 61 | 31 : 0; 62 | 32 : 0; 63 | 33 : 0; 64 | 34 : 1; 65 | 35 : 0; 66 | 36 : 0; -- M counter: Bypass = 0 (1 bit(s)) 67 | 37 : 0; -- M counter: High Count = 49 (8 bit(s)) 68 | 38 : 0; 69 | 39 : 1; 70 | 40 : 1; 71 | 41 : 0; 72 | 42 : 0; 73 | 43 : 0; 74 | 44 : 1; 75 | 45 : 1; -- M counter: Odd Division = 1 (1 bit(s)) 76 | 46 : 0; -- M counter: Low Count = 48 (8 bit(s)) 77 | 47 : 0; 78 | 48 : 1; 79 | 49 : 1; 80 | 50 : 0; 81 | 51 : 0; 82 | 52 : 0; 83 | 53 : 0; 84 | 54 : 0; -- clk0 counter: Bypass = 0 (1 bit(s)) 85 | 55 : 0; -- clk0 counter: High Count = 4 (8 bit(s)) 86 | 56 : 0; 87 | 57 : 0; 88 | 58 : 0; 89 | 59 : 0; 90 | 60 : 1; 91 | 61 : 0; 92 | 62 : 0; 93 | 63 : 0; -- clk0 counter: Odd Division = 0 (1 bit(s)) 94 | 64 : 0; -- clk0 counter: Low Count = 4 (8 bit(s)) 95 | 65 : 0; 96 | 66 : 0; 97 | 67 : 0; 98 | 68 : 0; 99 | 69 : 1; 100 | 70 : 0; 101 | 71 : 0; 102 | 72 : 0; -- clk1 counter: Bypass = 0 (1 bit(s)) 103 | 73 : 0; -- clk1 counter: High Count = 8 (8 bit(s)) 104 | 74 : 0; 105 | 75 : 0; 106 | 76 : 0; 107 | 77 : 1; 108 | 78 : 0; 109 | 79 : 0; 110 | 80 : 0; 111 | 81 : 0; -- clk1 counter: Odd Division = 0 (1 bit(s)) 112 | 82 : 0; -- clk1 counter: Low Count = 8 (8 bit(s)) 113 | 83 : 0; 114 | 84 : 0; 115 | 85 : 0; 116 | 86 : 1; 117 | 87 : 0; 118 | 88 : 0; 119 | 89 : 0; 120 | 90 : 0; -- clk2 counter: Bypass = 0 (1 bit(s)) 121 | 91 : 0; -- clk2 counter: High Count = 4 (8 bit(s)) 122 | 92 : 0; 123 | 93 : 0; 124 | 94 : 0; 125 | 95 : 0; 126 | 96 : 1; 127 | 97 : 0; 128 | 98 : 0; 129 | 99 : 0; -- clk2 counter: Odd Division = 0 (1 bit(s)) 130 | 100 : 0; -- clk2 counter: Low Count = 4 (8 bit(s)) 131 | 101 : 0; 132 | 102 : 0; 133 | 103 : 0; 134 | 104 : 0; 135 | 105 : 1; 136 | 106 : 0; 137 | 107 : 0; 138 | 108 : 1; -- clk3 counter: Bypass = 1 (1 bit(s)) 139 | 109 : 0; -- clk3 counter: High Count = 0 (8 bit(s)) 140 | 110 : 0; 141 | 111 : 0; 142 | 112 : 0; 143 | 113 : 0; 144 | 114 : 0; 145 | 115 : 0; 146 | 116 : 0; 147 | 117 : 0; -- clk3 counter: Odd Division = 0 (1 bit(s)) 148 | 118 : 0; -- clk3 counter: Low Count = 0 (8 bit(s)) 149 | 119 : 0; 150 | 120 : 0; 151 | 121 : 0; 152 | 122 : 0; 153 | 123 : 0; 154 | 124 : 0; 155 | 125 : 0; 156 | 126 : 1; -- clk4 counter: Bypass = 1 (1 bit(s)) 157 | 127 : 0; -- clk4 counter: High Count = 0 (8 bit(s)) 158 | 128 : 0; 159 | 129 : 0; 160 | 130 : 0; 161 | 131 : 0; 162 | 132 : 0; 163 | 133 : 0; 164 | 134 : 0; 165 | 135 : 0; -- clk4 counter: Odd Division = 0 (1 bit(s)) 166 | 136 : 0; -- clk4 counter: Low Count = 0 (8 bit(s)) 167 | 137 : 0; 168 | 138 : 0; 169 | 139 : 0; 170 | 140 : 0; 171 | 141 : 0; 172 | 142 : 0; 173 | 143 : 0; 174 | END; 175 | -------------------------------------------------------------------------------- /rtl/mist/cyc3/pll_c64_pal.mif: -------------------------------------------------------------------------------- 1 | -- Copyright (C) 1991-2014 Altera Corporation 2 | -- Your use of Altera Corporation's design tools, logic functions 3 | -- and other software and tools, and its AMPP partner logic 4 | -- functions, and any output files from any of the foregoing 5 | -- (including device programming or simulation files), and any 6 | -- associated documentation or information are expressly subject 7 | -- to the terms and conditions of the Altera Program License 8 | -- Subscription Agreement, Altera MegaCore Function License 9 | -- Agreement, or other applicable license agreement, including, 10 | -- without limitation, that your use is for the sole purpose of 11 | -- programming logic devices manufactured by Altera and sold by 12 | -- Altera or its authorized distributors. Please refer to the 13 | -- applicable agreement for further details. 14 | 15 | -- MIF file representing initial state of PLL Scan Chain 16 | -- Device Family: Cyclone III 17 | -- Device Part: - 18 | -- Device Speed Grade: 8 19 | -- PLL Scan Chain: Fast PLL (144 bits) 20 | -- File Name: /home/gyuri/git/c64/rtl/mist/cyc3/pll_c64_pal.mif 21 | -- Generated: Mon Apr 15 23:37:38 2024 22 | 23 | WIDTH=1; 24 | DEPTH=144; 25 | 26 | ADDRESS_RADIX=UNS; 27 | DATA_RADIX=UNS; 28 | 29 | CONTENT BEGIN 30 | 0 : 0; -- Reserved Bits = 0 (1 bit(s)) 31 | 1 : 0; -- Reserved Bits = 0 (1 bit(s)) 32 | 2 : 0; -- Loop Filter Capacitance = 0 (2 bit(s)) (Setting 0) 33 | 3 : 0; 34 | 4 : 1; -- Loop Filter Resistance = 24 (5 bit(s)) (Setting 24) 35 | 5 : 1; 36 | 6 : 0; 37 | 7 : 0; 38 | 8 : 0; 39 | 9 : 0; -- VCO Post Scale = 0 (1 bit(s)) (VCO post-scale divider counter value = 2) 40 | 10 : 0; -- Reserved Bits = 0 (5 bit(s)) 41 | 11 : 0; 42 | 12 : 0; 43 | 13 : 0; 44 | 14 : 0; 45 | 15 : 0; -- Charge Pump Current = 1 (3 bit(s)) (Setting 1) 46 | 16 : 0; 47 | 17 : 1; 48 | 18 : 1; -- N counter: Bypass = 1 (1 bit(s)) 49 | 19 : 0; -- N counter: High Count = 0 (8 bit(s)) 50 | 20 : 0; 51 | 21 : 0; 52 | 22 : 0; 53 | 23 : 0; 54 | 24 : 0; 55 | 25 : 0; 56 | 26 : 0; 57 | 27 : 0; -- N counter: Odd Division = 0 (1 bit(s)) 58 | 28 : 0; -- N counter: Low Count = 0 (8 bit(s)) 59 | 29 : 0; 60 | 30 : 0; 61 | 31 : 0; 62 | 32 : 0; 63 | 33 : 0; 64 | 34 : 0; 65 | 35 : 0; 66 | 36 : 0; -- M counter: Bypass = 0 (1 bit(s)) 67 | 37 : 0; -- M counter: High Count = 11 (8 bit(s)) 68 | 38 : 0; 69 | 39 : 0; 70 | 40 : 0; 71 | 41 : 1; 72 | 42 : 0; 73 | 43 : 1; 74 | 44 : 1; 75 | 45 : 1; -- M counter: Odd Division = 1 (1 bit(s)) 76 | 46 : 0; -- M counter: Low Count = 10 (8 bit(s)) 77 | 47 : 0; 78 | 48 : 0; 79 | 49 : 0; 80 | 50 : 1; 81 | 51 : 0; 82 | 52 : 1; 83 | 53 : 0; 84 | 54 : 0; -- clk0 counter: Bypass = 0 (1 bit(s)) 85 | 55 : 0; -- clk0 counter: High Count = 5 (8 bit(s)) 86 | 56 : 0; 87 | 57 : 0; 88 | 58 : 0; 89 | 59 : 0; 90 | 60 : 1; 91 | 61 : 0; 92 | 62 : 1; 93 | 63 : 1; -- clk0 counter: Odd Division = 1 (1 bit(s)) 94 | 64 : 0; -- clk0 counter: Low Count = 4 (8 bit(s)) 95 | 65 : 0; 96 | 66 : 0; 97 | 67 : 0; 98 | 68 : 0; 99 | 69 : 1; 100 | 70 : 0; 101 | 71 : 0; 102 | 72 : 0; -- clk1 counter: Bypass = 0 (1 bit(s)) 103 | 73 : 0; -- clk1 counter: High Count = 9 (8 bit(s)) 104 | 74 : 0; 105 | 75 : 0; 106 | 76 : 0; 107 | 77 : 1; 108 | 78 : 0; 109 | 79 : 0; 110 | 80 : 1; 111 | 81 : 0; -- clk1 counter: Odd Division = 0 (1 bit(s)) 112 | 82 : 0; -- clk1 counter: Low Count = 9 (8 bit(s)) 113 | 83 : 0; 114 | 84 : 0; 115 | 85 : 0; 116 | 86 : 1; 117 | 87 : 0; 118 | 88 : 0; 119 | 89 : 1; 120 | 90 : 0; -- clk2 counter: Bypass = 0 (1 bit(s)) 121 | 91 : 0; -- clk2 counter: High Count = 5 (8 bit(s)) 122 | 92 : 0; 123 | 93 : 0; 124 | 94 : 0; 125 | 95 : 0; 126 | 96 : 1; 127 | 97 : 0; 128 | 98 : 1; 129 | 99 : 1; -- clk2 counter: Odd Division = 1 (1 bit(s)) 130 | 100 : 0; -- clk2 counter: Low Count = 4 (8 bit(s)) 131 | 101 : 0; 132 | 102 : 0; 133 | 103 : 0; 134 | 104 : 0; 135 | 105 : 1; 136 | 106 : 0; 137 | 107 : 0; 138 | 108 : 1; -- clk3 counter: Bypass = 1 (1 bit(s)) 139 | 109 : 0; -- clk3 counter: High Count = 0 (8 bit(s)) 140 | 110 : 0; 141 | 111 : 0; 142 | 112 : 0; 143 | 113 : 0; 144 | 114 : 0; 145 | 115 : 0; 146 | 116 : 0; 147 | 117 : 0; -- clk3 counter: Odd Division = 0 (1 bit(s)) 148 | 118 : 0; -- clk3 counter: Low Count = 0 (8 bit(s)) 149 | 119 : 0; 150 | 120 : 0; 151 | 121 : 0; 152 | 122 : 0; 153 | 123 : 0; 154 | 124 : 0; 155 | 125 : 0; 156 | 126 : 1; -- clk4 counter: Bypass = 1 (1 bit(s)) 157 | 127 : 0; -- clk4 counter: High Count = 0 (8 bit(s)) 158 | 128 : 0; 159 | 129 : 0; 160 | 130 : 0; 161 | 131 : 0; 162 | 132 : 0; 163 | 133 : 0; 164 | 134 : 0; 165 | 135 : 0; -- clk4 counter: Odd Division = 0 (1 bit(s)) 166 | 136 : 0; -- clk4 counter: Low Count = 0 (8 bit(s)) 167 | 137 : 0; 168 | 138 : 0; 169 | 139 : 0; 170 | 140 : 0; 171 | 141 : 0; 172 | 142 : 0; 173 | 143 : 0; 174 | END; 175 | -------------------------------------------------------------------------------- /rtl/mist/cyc4gx/pll_c64_ntsc.mif: -------------------------------------------------------------------------------- 1 | -- Copyright (C) 2023 Intel Corporation. All rights reserved. 2 | -- Your use of Intel Corporation's design tools, logic functions 3 | -- and other software and tools, and any partner logic 4 | -- functions, and any output files from any of the foregoing 5 | -- (including device programming or simulation files), and any 6 | -- associated documentation or information are expressly subject 7 | -- to the terms and conditions of the Intel Program License 8 | -- Subscription Agreement, the Intel Quartus Prime License Agreement, 9 | -- the Intel FPGA IP License Agreement, or other applicable license 10 | -- agreement, including, without limitation, that your use is for 11 | -- the sole purpose of programming logic devices manufactured by 12 | -- Intel and sold by Intel or its authorized distributors. Please 13 | -- refer to the applicable agreement for further details, at 14 | -- https://fpgasoftware.intel.com/eula. 15 | 16 | -- MIF file representing initial state of PLL Scan Chain 17 | -- Device Family: Cyclone IV GX 18 | -- Device Part: - 19 | -- Device Speed Grade: - 20 | -- PLL Scan Chain: Cyclone III GX GPLL (144 bits) 21 | -- File Name: /home/gyuri/git/c64/rtl/mist/cyc4gx/pll_c64_ntsc.mif 22 | -- Generated: Tue Apr 16 00:37:11 2024 23 | 24 | WIDTH=1; 25 | DEPTH=144; 26 | 27 | ADDRESS_RADIX=UNS; 28 | DATA_RADIX=UNS; 29 | 30 | CONTENT BEGIN 31 | 0 : 0; -- Reserved Bits = 0 (1 bit(s)) 32 | 1 : 0; -- Reserved Bits = 0 (1 bit(s)) 33 | 2 : 0; -- Loop Filter Capacitance = 0 (2 bit(s)) (Setting 0) 34 | 3 : 0; 35 | 4 : 1; -- Loop Filter Resistance = 19 (5 bit(s)) (Setting 19) 36 | 5 : 0; 37 | 6 : 0; 38 | 7 : 1; 39 | 8 : 1; 40 | 9 : 0; -- VCO Post Scale = 0 (1 bit(s)) (VCO post-scale divider counter value = 2) 41 | 10 : 0; -- Reserved Bits = 0 (5 bit(s)) 42 | 11 : 0; 43 | 12 : 0; 44 | 13 : 0; 45 | 14 : 0; 46 | 15 : 0; -- Charge Pump Current = 1 (3 bit(s)) (Setting 1) 47 | 16 : 0; 48 | 17 : 1; 49 | 18 : 0; -- N counter: Bypass = 0 (1 bit(s)) 50 | 19 : 0; -- N counter: High Count = 4 (8 bit(s)) 51 | 20 : 0; 52 | 21 : 0; 53 | 22 : 0; 54 | 23 : 0; 55 | 24 : 1; 56 | 25 : 0; 57 | 26 : 0; 58 | 27 : 1; -- N counter: Odd Division = 1 (1 bit(s)) 59 | 28 : 0; -- N counter: Low Count = 3 (8 bit(s)) 60 | 29 : 0; 61 | 30 : 0; 62 | 31 : 0; 63 | 32 : 0; 64 | 33 : 0; 65 | 34 : 1; 66 | 35 : 1; 67 | 36 : 0; -- M counter: Bypass = 0 (1 bit(s)) 68 | 37 : 0; -- M counter: High Count = 28 (8 bit(s)) 69 | 38 : 0; 70 | 39 : 0; 71 | 40 : 1; 72 | 41 : 1; 73 | 42 : 1; 74 | 43 : 0; 75 | 44 : 0; 76 | 45 : 1; -- M counter: Odd Division = 1 (1 bit(s)) 77 | 46 : 0; -- M counter: Low Count = 27 (8 bit(s)) 78 | 47 : 0; 79 | 48 : 0; 80 | 49 : 1; 81 | 50 : 1; 82 | 51 : 0; 83 | 52 : 1; 84 | 53 : 1; 85 | 54 : 0; -- clk0 counter: Bypass = 0 (1 bit(s)) 86 | 55 : 0; -- clk0 counter: High Count = 3 (8 bit(s)) 87 | 56 : 0; 88 | 57 : 0; 89 | 58 : 0; 90 | 59 : 0; 91 | 60 : 0; 92 | 61 : 1; 93 | 62 : 1; 94 | 63 : 0; -- clk0 counter: Odd Division = 0 (1 bit(s)) 95 | 64 : 0; -- clk0 counter: Low Count = 3 (8 bit(s)) 96 | 65 : 0; 97 | 66 : 0; 98 | 67 : 0; 99 | 68 : 0; 100 | 69 : 0; 101 | 70 : 1; 102 | 71 : 1; 103 | 72 : 0; -- clk1 counter: Bypass = 0 (1 bit(s)) 104 | 73 : 0; -- clk1 counter: High Count = 6 (8 bit(s)) 105 | 74 : 0; 106 | 75 : 0; 107 | 76 : 0; 108 | 77 : 0; 109 | 78 : 1; 110 | 79 : 1; 111 | 80 : 0; 112 | 81 : 0; -- clk1 counter: Odd Division = 0 (1 bit(s)) 113 | 82 : 0; -- clk1 counter: Low Count = 6 (8 bit(s)) 114 | 83 : 0; 115 | 84 : 0; 116 | 85 : 0; 117 | 86 : 0; 118 | 87 : 1; 119 | 88 : 1; 120 | 89 : 0; 121 | 90 : 0; -- clk2 counter: Bypass = 0 (1 bit(s)) 122 | 91 : 0; -- clk2 counter: High Count = 3 (8 bit(s)) 123 | 92 : 0; 124 | 93 : 0; 125 | 94 : 0; 126 | 95 : 0; 127 | 96 : 0; 128 | 97 : 1; 129 | 98 : 1; 130 | 99 : 0; -- clk2 counter: Odd Division = 0 (1 bit(s)) 131 | 100 : 0; -- clk2 counter: Low Count = 3 (8 bit(s)) 132 | 101 : 0; 133 | 102 : 0; 134 | 103 : 0; 135 | 104 : 0; 136 | 105 : 0; 137 | 106 : 1; 138 | 107 : 1; 139 | 108 : 1; -- clk3 counter: Bypass = 1 (1 bit(s)) 140 | 109 : 0; -- clk3 counter: High Count = 0 (8 bit(s)) 141 | 110 : 0; 142 | 111 : 0; 143 | 112 : 0; 144 | 113 : 0; 145 | 114 : 0; 146 | 115 : 0; 147 | 116 : 0; 148 | 117 : 0; -- clk3 counter: Odd Division = 0 (1 bit(s)) 149 | 118 : 0; -- clk3 counter: Low Count = 0 (8 bit(s)) 150 | 119 : 0; 151 | 120 : 0; 152 | 121 : 0; 153 | 122 : 0; 154 | 123 : 0; 155 | 124 : 0; 156 | 125 : 0; 157 | 126 : 1; -- clk4 counter: Bypass = 1 (1 bit(s)) 158 | 127 : 0; -- clk4 counter: High Count = 0 (8 bit(s)) 159 | 128 : 0; 160 | 129 : 0; 161 | 130 : 0; 162 | 131 : 0; 163 | 132 : 0; 164 | 133 : 0; 165 | 134 : 0; 166 | 135 : 0; -- clk4 counter: Odd Division = 0 (1 bit(s)) 167 | 136 : 0; -- clk4 counter: Low Count = 0 (8 bit(s)) 168 | 137 : 0; 169 | 138 : 0; 170 | 139 : 0; 171 | 140 : 0; 172 | 141 : 0; 173 | 142 : 0; 174 | 143 : 0; 175 | END; 176 | -------------------------------------------------------------------------------- /rtl/mist/cyc4gx/pll_c64_pal.mif: -------------------------------------------------------------------------------- 1 | -- Copyright (C) 2023 Intel Corporation. All rights reserved. 2 | -- Your use of Intel Corporation's design tools, logic functions 3 | -- and other software and tools, and any partner logic 4 | -- functions, and any output files from any of the foregoing 5 | -- (including device programming or simulation files), and any 6 | -- associated documentation or information are expressly subject 7 | -- to the terms and conditions of the Intel Program License 8 | -- Subscription Agreement, the Intel Quartus Prime License Agreement, 9 | -- the Intel FPGA IP License Agreement, or other applicable license 10 | -- agreement, including, without limitation, that your use is for 11 | -- the sole purpose of programming logic devices manufactured by 12 | -- Intel and sold by Intel or its authorized distributors. Please 13 | -- refer to the applicable agreement for further details, at 14 | -- https://fpgasoftware.intel.com/eula. 15 | 16 | -- MIF file representing initial state of PLL Scan Chain 17 | -- Device Family: Cyclone IV GX 18 | -- Device Part: - 19 | -- Device Speed Grade: - 20 | -- PLL Scan Chain: Cyclone III GX GPLL (144 bits) 21 | -- File Name: /home/gyuri/git/c64/rtl/mist/cyc4gx/pll_c64_pal.mif 22 | -- Generated: Tue Apr 16 00:41:46 2024 23 | 24 | WIDTH=1; 25 | DEPTH=144; 26 | 27 | ADDRESS_RADIX=UNS; 28 | DATA_RADIX=UNS; 29 | 30 | CONTENT BEGIN 31 | 0 : 0; -- Reserved Bits = 0 (1 bit(s)) 32 | 1 : 0; -- Reserved Bits = 0 (1 bit(s)) 33 | 2 : 0; -- Loop Filter Capacitance = 0 (2 bit(s)) (Setting 0) 34 | 3 : 0; 35 | 4 : 1; -- Loop Filter Resistance = 19 (5 bit(s)) (Setting 19) 36 | 5 : 0; 37 | 6 : 0; 38 | 7 : 1; 39 | 8 : 1; 40 | 9 : 0; -- VCO Post Scale = 0 (1 bit(s)) (VCO post-scale divider counter value = 2) 41 | 10 : 0; -- Reserved Bits = 0 (5 bit(s)) 42 | 11 : 0; 43 | 12 : 0; 44 | 13 : 0; 45 | 14 : 0; 46 | 15 : 0; -- Charge Pump Current = 1 (3 bit(s)) (Setting 1) 47 | 16 : 0; 48 | 17 : 1; 49 | 18 : 0; -- N counter: Bypass = 0 (1 bit(s)) 50 | 19 : 0; -- N counter: High Count = 4 (8 bit(s)) 51 | 20 : 0; 52 | 21 : 0; 53 | 22 : 0; 54 | 23 : 0; 55 | 24 : 1; 56 | 25 : 0; 57 | 26 : 0; 58 | 27 : 1; -- N counter: Odd Division = 1 (1 bit(s)) 59 | 28 : 0; -- N counter: Low Count = 3 (8 bit(s)) 60 | 29 : 0; 61 | 30 : 0; 62 | 31 : 0; 63 | 32 : 0; 64 | 33 : 0; 65 | 34 : 1; 66 | 35 : 1; 67 | 36 : 0; -- M counter: Bypass = 0 (1 bit(s)) 68 | 37 : 0; -- M counter: High Count = 27 (8 bit(s)) 69 | 38 : 0; 70 | 39 : 0; 71 | 40 : 1; 72 | 41 : 1; 73 | 42 : 0; 74 | 43 : 1; 75 | 44 : 1; 76 | 45 : 1; -- M counter: Odd Division = 1 (1 bit(s)) 77 | 46 : 0; -- M counter: Low Count = 26 (8 bit(s)) 78 | 47 : 0; 79 | 48 : 0; 80 | 49 : 1; 81 | 50 : 1; 82 | 51 : 0; 83 | 52 : 1; 84 | 53 : 0; 85 | 54 : 0; -- clk0 counter: Bypass = 0 (1 bit(s)) 86 | 55 : 0; -- clk0 counter: High Count = 3 (8 bit(s)) 87 | 56 : 0; 88 | 57 : 0; 89 | 58 : 0; 90 | 59 : 0; 91 | 60 : 0; 92 | 61 : 1; 93 | 62 : 1; 94 | 63 : 0; -- clk0 counter: Odd Division = 0 (1 bit(s)) 95 | 64 : 0; -- clk0 counter: Low Count = 3 (8 bit(s)) 96 | 65 : 0; 97 | 66 : 0; 98 | 67 : 0; 99 | 68 : 0; 100 | 69 : 0; 101 | 70 : 1; 102 | 71 : 1; 103 | 72 : 0; -- clk1 counter: Bypass = 0 (1 bit(s)) 104 | 73 : 0; -- clk1 counter: High Count = 6 (8 bit(s)) 105 | 74 : 0; 106 | 75 : 0; 107 | 76 : 0; 108 | 77 : 0; 109 | 78 : 1; 110 | 79 : 1; 111 | 80 : 0; 112 | 81 : 0; -- clk1 counter: Odd Division = 0 (1 bit(s)) 113 | 82 : 0; -- clk1 counter: Low Count = 6 (8 bit(s)) 114 | 83 : 0; 115 | 84 : 0; 116 | 85 : 0; 117 | 86 : 0; 118 | 87 : 1; 119 | 88 : 1; 120 | 89 : 0; 121 | 90 : 0; -- clk2 counter: Bypass = 0 (1 bit(s)) 122 | 91 : 0; -- clk2 counter: High Count = 3 (8 bit(s)) 123 | 92 : 0; 124 | 93 : 0; 125 | 94 : 0; 126 | 95 : 0; 127 | 96 : 0; 128 | 97 : 1; 129 | 98 : 1; 130 | 99 : 0; -- clk2 counter: Odd Division = 0 (1 bit(s)) 131 | 100 : 0; -- clk2 counter: Low Count = 3 (8 bit(s)) 132 | 101 : 0; 133 | 102 : 0; 134 | 103 : 0; 135 | 104 : 0; 136 | 105 : 0; 137 | 106 : 1; 138 | 107 : 1; 139 | 108 : 1; -- clk3 counter: Bypass = 1 (1 bit(s)) 140 | 109 : 0; -- clk3 counter: High Count = 0 (8 bit(s)) 141 | 110 : 0; 142 | 111 : 0; 143 | 112 : 0; 144 | 113 : 0; 145 | 114 : 0; 146 | 115 : 0; 147 | 116 : 0; 148 | 117 : 0; -- clk3 counter: Odd Division = 0 (1 bit(s)) 149 | 118 : 0; -- clk3 counter: Low Count = 0 (8 bit(s)) 150 | 119 : 0; 151 | 120 : 0; 152 | 121 : 0; 153 | 122 : 0; 154 | 123 : 0; 155 | 124 : 0; 156 | 125 : 0; 157 | 126 : 1; -- clk4 counter: Bypass = 1 (1 bit(s)) 158 | 127 : 0; -- clk4 counter: High Count = 0 (8 bit(s)) 159 | 128 : 0; 160 | 129 : 0; 161 | 130 : 0; 162 | 131 : 0; 163 | 132 : 0; 164 | 133 : 0; 165 | 134 : 0; 166 | 135 : 0; -- clk4 counter: Odd Division = 0 (1 bit(s)) 167 | 136 : 0; -- clk4 counter: Low Count = 0 (8 bit(s)) 168 | 137 : 0; 169 | 138 : 0; 170 | 139 : 0; 171 | 140 : 0; 172 | 141 : 0; 173 | 142 : 0; 174 | 143 : 0; 175 | END; 176 | -------------------------------------------------------------------------------- /rtl/mist/sigma_delta_dac.v: -------------------------------------------------------------------------------- 1 | 2 | // sigmadelta.v 3 | // two channel second order sigma delta dac 4 | // taken from Minimig 5 | 6 | // audio data processing 7 | // stereo sigma/delta bitstream modulator 8 | module sigma_delta_dac ( 9 | input clk, // bus clock 10 | input [14:0] ldatasum, // left channel data 11 | input [14:0] rdatasum, // right channel data 12 | output reg aleft=0, // left bitstream output 13 | output reg aright=0 // right bitsteam output 14 | ); 15 | 16 | //-------------------------------------------------------------------------------------- 17 | 18 | // local signals 19 | localparam DW = 15; 20 | localparam CW = 2; 21 | localparam RW = 4; 22 | localparam A1W = 2; 23 | localparam A2W = 5; 24 | 25 | wire [DW+2+0 -1:0] sd_l_er0, sd_r_er0; 26 | reg [DW+2+0 -1:0] sd_l_er0_prev=0, sd_r_er0_prev=0; 27 | wire [DW+A1W+2-1:0] sd_l_aca1, sd_r_aca1; 28 | wire [DW+A2W+2-1:0] sd_l_aca2, sd_r_aca2; 29 | reg [DW+A1W+2-1:0] sd_l_ac1=0, sd_r_ac1=0; 30 | reg [DW+A2W+2-1:0] sd_l_ac2=0, sd_r_ac2=0; 31 | wire [DW+A2W+3-1:0] sd_l_quant, sd_r_quant; 32 | 33 | // LPF noise LFSR 34 | reg [24-1:0] seed1 = 24'h654321; 35 | reg [19-1:0] seed2 = 19'h12345; 36 | reg [24-1:0] seed_sum=0, seed_prev=0, seed_out=0; 37 | always @ (posedge clk) begin 38 | if (&seed1) 39 | seed1 <= #1 24'h654321; 40 | else 41 | seed1 <= #1 {seed1[22:0], ~(seed1[23] ^ seed1[22] ^ seed1[21] ^ seed1[16])}; 42 | end 43 | always @ (posedge clk) begin 44 | if (&seed2) 45 | seed2 <= #1 19'h12345; 46 | else 47 | seed2 <= #1 {seed2[17:0], ~(seed2[18] ^ seed2[17] ^ seed2[16] ^ seed2[13] ^ seed2[0])}; 48 | end 49 | always @ (posedge clk) begin 50 | seed_sum <= #1 seed1 + {5'b0, seed2}; 51 | seed_prev <= #1 seed_sum; 52 | seed_out <= #1 seed_sum - seed_prev; 53 | end 54 | 55 | // linear interpolate 56 | localparam ID=4; // counter size, also 2^ID = interpolation rate 57 | reg [ID+0-1:0] int_cnt = 0; 58 | always @ (posedge clk) int_cnt <= #1 int_cnt + 'd1; 59 | 60 | reg [DW+0-1:0] ldata_cur=0, ldata_prev=0; 61 | reg [DW+0-1:0] rdata_cur=0, rdata_prev=0; 62 | wire [DW+1-1:0] ldata_step, rdata_step; 63 | reg [DW+ID-1:0] ldata_int=0, rdata_int=0; 64 | wire [DW+0-1:0] ldata_int_out, rdata_int_out; 65 | assign ldata_step = {ldata_cur[DW-1], ldata_cur} - {ldata_prev[DW-1], ldata_prev}; // signed subtract 66 | assign rdata_step = {rdata_cur[DW-1], rdata_cur} - {rdata_prev[DW-1], rdata_prev}; // signed subtract 67 | always @ (posedge clk) begin 68 | if (~|int_cnt) begin 69 | ldata_prev <= #1 ldata_cur; 70 | ldata_cur <= #1 ldatasum; //{~ldatasum[DW-1], ldatasum[DW-2:0]}; // convert to offset binary, samples no longer signed! 71 | rdata_prev <= #1 rdata_cur; 72 | rdata_cur <= #1 rdatasum; //{~rdatasum[DW-1], rdatasum[DW-2:0]}; // convert to offset binary, samples no longer signed! 73 | ldata_int <= #1 {ldata_cur[DW-1], ldata_cur, {ID{1'b0}}}; 74 | rdata_int <= #1 {rdata_cur[DW-1], rdata_cur, {ID{1'b0}}}; 75 | end else begin 76 | ldata_int <= #1 ldata_int + {{ID{ldata_step[DW+1-1]}}, ldata_step}; 77 | rdata_int <= #1 rdata_int + {{ID{rdata_step[DW+1-1]}}, rdata_step}; 78 | end 79 | end 80 | assign ldata_int_out = ldata_int[DW+ID-1:ID]; 81 | assign rdata_int_out = rdata_int[DW+ID-1:ID]; 82 | 83 | // input gain x3 84 | wire [DW+2-1:0] ldata_gain, rdata_gain; 85 | assign ldata_gain = {ldata_int_out[DW-1], ldata_int_out, 1'b0} + {{(2){ldata_int_out[DW-1]}}, ldata_int_out}; 86 | assign rdata_gain = {rdata_int_out[DW-1], rdata_int_out, 1'b0} + {{(2){rdata_int_out[DW-1]}}, rdata_int_out}; 87 | 88 | /* 89 | // random dither to 15 bits 90 | reg [DW-1:0] ldata=0, rdata=0; 91 | always @ (posedge clk) begin 92 | ldata <= #1 ldata_gain[DW+2-1:2] + ( (~(&ldata_gain[DW+2-1-1:2]) && (ldata_gain[1:0] > seed_out[1:0])) ? 15'd1 : 15'd0 ); 93 | rdata <= #1 rdata_gain[DW+2-1:2] + ( (~(&ldata_gain[DW+2-1-1:2]) && (ldata_gain[1:0] > seed_out[1:0])) ? 15'd1 : 15'd0 ); 94 | end 95 | */ 96 | 97 | // accumulator adders 98 | assign sd_l_aca1 = {{(A1W){ldata_gain[DW+2-1]}}, ldata_gain} - {{(A1W){sd_l_er0[DW+2-1]}}, sd_l_er0} + sd_l_ac1; 99 | assign sd_r_aca1 = {{(A1W){rdata_gain[DW+2-1]}}, rdata_gain} - {{(A1W){sd_r_er0[DW+2-1]}}, sd_r_er0} + sd_r_ac1; 100 | 101 | assign sd_l_aca2 = {{(A2W-A1W){sd_l_aca1[DW+A1W+2-1]}}, sd_l_aca1} - {{(A2W){sd_l_er0[DW+2-1]}}, sd_l_er0} - {{(A2W+1){sd_l_er0_prev[DW+2-1]}}, sd_l_er0_prev[DW+2-1:1]} + sd_l_ac2; 102 | assign sd_r_aca2 = {{(A2W-A1W){sd_r_aca1[DW+A1W+2-1]}}, sd_r_aca1} - {{(A2W){sd_r_er0[DW+2-1]}}, sd_r_er0} - {{(A2W+1){sd_r_er0_prev[DW+2-1]}}, sd_r_er0_prev[DW+2-1:1]} + sd_r_ac2; 103 | 104 | // accumulators 105 | always @ (posedge clk) begin 106 | sd_l_ac1 <= #1 sd_l_aca1; 107 | sd_r_ac1 <= #1 sd_r_aca1; 108 | sd_l_ac2 <= #1 sd_l_aca2; 109 | sd_r_ac2 <= #1 sd_r_aca2; 110 | end 111 | 112 | // value for quantizaton 113 | assign sd_l_quant = {sd_l_ac2[DW+A2W+2-1], sd_l_ac2} + {{(DW+A2W+3-RW){seed_out[RW-1]}}, seed_out[RW-1:0]}; 114 | assign sd_r_quant = {sd_r_ac2[DW+A2W+2-1], sd_r_ac2} + {{(DW+A2W+3-RW){seed_out[RW-1]}}, seed_out[RW-1:0]}; 115 | 116 | // error feedback 117 | assign sd_l_er0 = sd_l_quant[DW+A2W+3-1] ? {1'b1, {(DW+2-1){1'b0}}} : {1'b0, {(DW+2-1){1'b1}}}; 118 | assign sd_r_er0 = sd_r_quant[DW+A2W+3-1] ? {1'b1, {(DW+2-1){1'b0}}} : {1'b0, {(DW+2-1){1'b1}}}; 119 | always @ (posedge clk) begin 120 | sd_l_er0_prev <= #1 (&sd_l_er0) ? sd_l_er0 : sd_l_er0+1; 121 | sd_r_er0_prev <= #1 (&sd_r_er0) ? sd_r_er0 : sd_r_er0+1; 122 | end 123 | 124 | // output 125 | always @ (posedge clk) begin 126 | aleft <= #1 (~|ldata_gain) ? ~aleft : ~sd_l_er0[DW+2-1]; 127 | aright <= #1 (~|rdata_gain) ? ~aright : ~sd_r_er0[DW+2-1]; 128 | end 129 | 130 | endmodule -------------------------------------------------------------------------------- /rtl/mist/sdram.v: -------------------------------------------------------------------------------- 1 | // 2 | // sdram.v 3 | // 4 | // sdram controller implementation for the MiST board 5 | // http://code.google.com/p/mist-board/ 6 | // 7 | // Copyright (c) 2013 Till Harbaum 8 | // 9 | // This source file is free software: you can redistribute it and/or modify 10 | // it under the terms of the GNU General Public License as published 11 | // by the Free Software Foundation, either version 3 of the License, or 12 | // (at your option) any later version. 13 | // 14 | // This source file is distributed in the hope that it will be useful, 15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | // GNU General Public License for more details. 18 | // 19 | // You should have received a copy of the GNU General Public License 20 | // along with this program. If not, see . 21 | // 22 | 23 | module sdram ( 24 | 25 | // interface to the MT48LC16M16 chip 26 | output reg [12:0] sd_addr, // 13 bit multiplexed address bus 27 | inout reg [15:0] sd_data, 28 | output reg [ 1:0] sd_ba, // two banks 29 | output sd_cs, // a single chip select 30 | output sd_we, // write enable 31 | output sd_ras, // row address select 32 | output sd_cas, // columns address select 33 | output reg sd_dqml, 34 | output reg sd_dqmh, 35 | 36 | // cpu/chipset interface 37 | input init, // init signal after FPGA config to initialize RAM 38 | input clk, // sdram is accessed at up to 128MHz 39 | 40 | input [1:0] bs, // byte selects 41 | input [23:0] addr, // 24 bit byte address 42 | input [15:0] din, 43 | output reg [15:0] dout, 44 | 45 | input refresh, // refresh cycle 46 | input ce, // cpu/chipset access 47 | input we // cpu/chipset requests write 48 | ); 49 | 50 | // no burst configured 51 | localparam RASCAS_DELAY = 3'd2; // tRCD>=20ns -> 2 cycles@64MHz 52 | localparam BURST_LENGTH = 3'b000; // 000=none, 001=2, 010=4, 011=8 53 | localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved 54 | localparam CAS_LATENCY = 3'd2; // 2/3 allowed 55 | localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed 56 | localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single access write 57 | 58 | localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH}; 59 | 60 | // --------------------------------------------------------------------- 61 | // ------------------------ cycle state machine ------------------------ 62 | // --------------------------------------------------------------------- 63 | 64 | localparam STATE_IDLE = 3'd0; // first state in cycle 65 | localparam STATE_CMD_START = 3'd0; // state in which a new command can be started 66 | localparam STATE_CMD_CONT = STATE_CMD_START + RASCAS_DELAY; // 2 command can be continued 67 | localparam STATE_CMD_DATA = STATE_CMD_CONT + CAS_LATENCY + 1'd1; 68 | localparam STATE_LAST = 3'd7; // last state in cycle 69 | 70 | reg [2:0] q /* synthesis noprune */; 71 | reg last_ce, last_refresh; 72 | always @(posedge clk) begin 73 | last_ce <= ce; 74 | last_refresh <= refresh; 75 | 76 | // start a new cycle in rising edge of ce or refresh 77 | if((ce && !last_ce) || (refresh && !last_refresh)) 78 | q <= 3'd1; 79 | 80 | if(q != 0) 81 | q <= q + 3'd1; 82 | 83 | end 84 | 85 | // --------------------------------------------------------------------- 86 | // --------------------------- startup/reset --------------------------- 87 | // --------------------------------------------------------------------- 88 | 89 | // wait 1ms (32 clkref cycles) after FPGA config is done before going 90 | // into normal operation. Initialize the ram in the last 16 reset cycles (cycles 15-0) 91 | reg [4:0] reset; 92 | always @(posedge clk) begin 93 | if(init) reset <= 5'h1f; 94 | else if((q == STATE_LAST) && (reset != 0)) 95 | reset <= reset - 5'd1; 96 | end 97 | 98 | // --------------------------------------------------------------------- 99 | // ------------------ generate ram control signals --------------------- 100 | // --------------------------------------------------------------------- 101 | 102 | // all possible commands 103 | localparam CMD_INHIBIT = 4'b1111; 104 | localparam CMD_NOP = 4'b0111; 105 | localparam CMD_ACTIVE = 4'b0011; 106 | localparam CMD_READ = 4'b0101; 107 | localparam CMD_WRITE = 4'b0100; 108 | localparam CMD_BURST_TERMINATE = 4'b0110; 109 | localparam CMD_PRECHARGE = 4'b0010; 110 | localparam CMD_AUTO_REFRESH = 4'b0001; 111 | localparam CMD_LOAD_MODE = 4'b0000; 112 | 113 | reg [3:0] sd_cmd; // current command sent to sd ram 114 | 115 | // drive control signals according to current command 116 | assign sd_cs = sd_cmd[3]; 117 | assign sd_ras = sd_cmd[2]; 118 | assign sd_cas = sd_cmd[1]; 119 | assign sd_we = sd_cmd[0]; 120 | wire [12:0] reset_addr = (reset == 13)?13'b0010000000000:MODE; 121 | wire [12:0] run_addr = (q == STATE_CMD_START)?addr[20:8]:{ 4'b0010, addr[23], addr[7:0]}; 122 | 123 | always @(posedge clk) begin 124 | sd_cmd <= CMD_INHIBIT; 125 | sd_addr <= (reset != 0)?reset_addr:run_addr; 126 | sd_ba <= addr[22:21]; 127 | sd_data <= 16'bZZZZZZZZZZZZZZZZ; 128 | sd_dqml <= 1; 129 | sd_dqmh <= 1; 130 | 131 | if(reset != 0) begin 132 | if(q == STATE_IDLE) begin 133 | if(reset == 13) sd_cmd <= CMD_PRECHARGE; 134 | if(reset == 2) sd_cmd <= CMD_LOAD_MODE; 135 | end 136 | end else begin 137 | if(q == STATE_IDLE) begin 138 | if(ce && !last_ce) sd_cmd <= CMD_ACTIVE; 139 | if(refresh && !last_refresh) sd_cmd <= CMD_AUTO_REFRESH; 140 | end else if((q == STATE_CMD_CONT)&&(!refresh)) begin 141 | if(we) begin 142 | sd_cmd <= CMD_WRITE; 143 | sd_data <= din; 144 | sd_dqml <= ~bs[0]; 145 | sd_dqmh <= ~bs[1]; 146 | end else if(ce) begin 147 | sd_cmd <= CMD_READ; 148 | sd_dqml <= 0; 149 | sd_dqmh <= 0; 150 | end 151 | end else if((q == STATE_CMD_DATA) && ce && !we && !refresh) begin 152 | dout <= sd_data; 153 | end 154 | end 155 | end 156 | 157 | endmodule 158 | -------------------------------------------------------------------------------- /rtl/mist/c64_mist_top.sv: -------------------------------------------------------------------------------- 1 | module c64_mist_top( 2 | input CLOCK_27, 3 | `ifdef USE_CLOCK_50 4 | input CLOCK_50, 5 | `endif 6 | 7 | output LED, 8 | output [VGA_BITS-1:0] VGA_R, 9 | output [VGA_BITS-1:0] VGA_G, 10 | output [VGA_BITS-1:0] VGA_B, 11 | output VGA_HS, 12 | output VGA_VS, 13 | 14 | `ifdef USE_HDMI 15 | output HDMI_RST, 16 | output [7:0] HDMI_R, 17 | output [7:0] HDMI_G, 18 | output [7:0] HDMI_B, 19 | output HDMI_HS, 20 | output HDMI_VS, 21 | output HDMI_PCLK, 22 | output HDMI_DE, 23 | inout HDMI_SDA, 24 | inout HDMI_SCL, 25 | input HDMI_INT, 26 | `endif 27 | 28 | input SPI_SCK, 29 | inout SPI_DO, 30 | input SPI_DI, 31 | input SPI_SS2, // data_io 32 | input SPI_SS3, // OSD 33 | input CONF_DATA0, // SPI_SS for user_io 34 | 35 | `ifdef USE_QSPI 36 | input QSCK, 37 | input QCSn, 38 | inout [3:0] QDAT, 39 | `endif 40 | `ifndef NO_DIRECT_UPLOAD 41 | input SPI_SS4, 42 | `endif 43 | 44 | output [12:0] SDRAM_A, 45 | inout [15:0] SDRAM_DQ, 46 | output SDRAM_DQML, 47 | output SDRAM_DQMH, 48 | output SDRAM_nWE, 49 | output SDRAM_nCAS, 50 | output SDRAM_nRAS, 51 | output SDRAM_nCS, 52 | output [1:0] SDRAM_BA, 53 | output SDRAM_CLK, 54 | output SDRAM_CKE, 55 | 56 | `ifdef DUAL_SDRAM 57 | output [12:0] SDRAM2_A, 58 | inout [15:0] SDRAM2_DQ, 59 | output SDRAM2_DQML, 60 | output SDRAM2_DQMH, 61 | output SDRAM2_nWE, 62 | output SDRAM2_nCAS, 63 | output SDRAM2_nRAS, 64 | output SDRAM2_nCS, 65 | output [1:0] SDRAM2_BA, 66 | output SDRAM2_CLK, 67 | output SDRAM2_CKE, 68 | `endif 69 | 70 | output AUDIO_L, 71 | output AUDIO_R, 72 | `ifdef I2S_AUDIO 73 | output I2S_BCK, 74 | output I2S_LRCK, 75 | output I2S_DATA, 76 | `endif 77 | `ifdef I2S_AUDIO_HDMI 78 | output HDMI_MCLK, 79 | output HDMI_BCK, 80 | output HDMI_LRCK, 81 | output HDMI_SDATA, 82 | `endif 83 | `ifdef SPDIF_AUDIO 84 | output SPDIF, 85 | `endif 86 | `ifdef USE_AUDIO_IN 87 | input AUDIO_IN, 88 | `endif 89 | `ifdef SIDI128_EXPANSION 90 | input UART_CTS, 91 | output UART_RTS, 92 | inout EXP7, 93 | inout MOTOR_CTRL, 94 | `endif 95 | `ifdef USE_MIDI_PINS 96 | input MIDI_IN, 97 | output MIDI_OUT, 98 | `endif 99 | input UART_RX, 100 | output UART_TX 101 | 102 | ); 103 | 104 | `ifdef NO_DIRECT_UPLOAD 105 | localparam bit DIRECT_UPLOAD = 0; 106 | wire SPI_SS4 = 1; 107 | `else 108 | localparam bit DIRECT_UPLOAD = 1; 109 | `endif 110 | 111 | `ifdef USE_QSPI 112 | localparam bit QSPI = 1; 113 | assign QDAT = 4'hZ; 114 | `else 115 | localparam bit QSPI = 0; 116 | `endif 117 | 118 | `ifdef VGA_8BIT 119 | localparam VGA_BITS = 8; 120 | `else 121 | localparam VGA_BITS = 6; 122 | `endif 123 | 124 | `ifdef USE_HDMI 125 | localparam bit HDMI = 1; 126 | assign HDMI_RST = 1'b1; 127 | `else 128 | localparam bit HDMI = 0; 129 | `endif 130 | 131 | `ifdef BIG_OSD 132 | localparam bit BIG_OSD = 1; 133 | `define SEP "-;", 134 | `else 135 | localparam bit BIG_OSD = 0; 136 | `define SEP 137 | `endif 138 | 139 | `ifdef USE_AUDIO_IN 140 | localparam bit USE_AUDIO_IN = 1; 141 | `else 142 | localparam bit USE_AUDIO_IN = 0; 143 | `endif 144 | 145 | `ifdef USE_MIDI_PINS 146 | localparam bit USE_MIDI_PINS = 1; 147 | `else 148 | localparam bit USE_MIDI_PINS = 0; 149 | `endif 150 | 151 | // remove this if the 2nd chip is actually used 152 | `ifdef DUAL_SDRAM 153 | assign SDRAM2_A = 13'hZZZZ; 154 | assign SDRAM2_BA = 0; 155 | assign SDRAM2_DQML = 0; 156 | assign SDRAM2_DQMH = 0; 157 | assign SDRAM2_CKE = 0; 158 | assign SDRAM2_CLK = 0; 159 | assign SDRAM2_nCS = 1; 160 | assign SDRAM2_DQ = 16'hZZZZ; 161 | assign SDRAM2_nCAS = 1; 162 | assign SDRAM2_nRAS = 1; 163 | assign SDRAM2_nWE = 1; 164 | `endif 165 | 166 | `include "build_id.v" 167 | 168 | `ifdef I2S_AUDIO 169 | `ifdef I2S_AUDIO_HDMI 170 | assign HDMI_MCLK = 0; 171 | assign HDMI_BCK = I2S_BCK; 172 | assign HDMI_LRCK = I2S_LRCK; 173 | assign HDMI_SDATA = I2S_DATA; 174 | `endif 175 | `endif 176 | 177 | `ifdef DRIVE_N 178 | localparam integer DRIVE_N = `DRIVE_N; 179 | `else 180 | localparam integer DRIVE_N = 1; 181 | `endif 182 | 183 | `ifdef SIDI128_EXPANSION 184 | assign EXP7 = 1'bZ; 185 | `endif 186 | 187 | c64_mist 188 | #( 189 | .VGA_BITS(VGA_BITS), 190 | .DIRECT_UPLOAD(DIRECT_UPLOAD ? "true" : "false"), 191 | .USE_AUDIO_IN(USE_AUDIO_IN ? "true" : "false"), 192 | .USE_MIDI_PINS(USE_MIDI_PINS ? "true" : "false"), 193 | .BIG_OSD(BIG_OSD ? "true" : "false"), 194 | .HDMI(HDMI ? "true" : "false"), 195 | .DRIVE_N(DRIVE_N), 196 | .BUILD_DATE(`BUILD_DATE) 197 | ) 198 | c64_mist ( 199 | `ifdef CLOCK_IN_50 200 | .CLOCK_IN(CLOCK_50), 201 | `else 202 | .CLOCK_IN(CLOCK_27), 203 | `endif 204 | .LED(LED), 205 | .VGA_R(VGA_R), 206 | .VGA_G(VGA_G), 207 | .VGA_B(VGA_B), 208 | .VGA_HS(VGA_HS), 209 | .VGA_VS(VGA_VS), 210 | `ifdef USE_HDMI 211 | .HDMI_R(HDMI_R), 212 | .HDMI_G(HDMI_G), 213 | .HDMI_B(HDMI_B), 214 | .HDMI_HS(HDMI_HS), 215 | .HDMI_VS(HDMI_VS), 216 | .HDMI_DE(HDMI_DE), 217 | .HDMI_PCLK(HDMI_PCLK), 218 | .HDMI_SCL(HDMI_SCL), 219 | .HDMI_SDA(HDMI_SDA), 220 | `endif 221 | 222 | .AUDIO_L(AUDIO_L), 223 | .AUDIO_R(AUDIO_R), 224 | `ifdef I2S_AUDIO 225 | .I2S_BCK(I2S_BCK), 226 | .I2S_LRCK(I2S_LRCK), 227 | .I2S_DATA(I2S_DATA), 228 | `endif 229 | `ifdef SPDIF_AUDIO 230 | .SPDIF_O(SPDIF), 231 | `endif 232 | `ifdef USE_AUDIO_IN 233 | .AUDIO_IN(AUDIO_IN), 234 | `endif 235 | `ifdef USE_MIDI_PINS 236 | .MIDI_IN(MIDI_IN), 237 | .MIDI_OUT(MIDI_OUT), 238 | `endif 239 | .SPI_SCK(SPI_SCK), 240 | .SPI_DO(SPI_DO), 241 | .SPI_DI(SPI_DI), 242 | .SPI_SS2(SPI_SS2), 243 | .SPI_SS3(SPI_SS3), 244 | .CONF_DATA0(CONF_DATA0), 245 | .SPI_SS4(SPI_SS4), 246 | 247 | .SDRAM_A(SDRAM_A), 248 | .SDRAM_DQ(SDRAM_DQ), 249 | .SDRAM_DQML(SDRAM_DQML), 250 | .SDRAM_DQMH(SDRAM_DQMH), 251 | .SDRAM_nWE(SDRAM_nWE), 252 | .SDRAM_nCAS(SDRAM_nCAS), 253 | .SDRAM_nRAS(SDRAM_nRAS), 254 | .SDRAM_nCS(SDRAM_nCS), 255 | .SDRAM_BA(SDRAM_BA), 256 | .SDRAM_CLK(SDRAM_CLK), 257 | .SDRAM_CKE(SDRAM_CKE), 258 | 259 | `ifdef SIDI128_EXPANSION 260 | .UART_CTS(UART_CTS), 261 | .UART_RTS(UART_RTS), 262 | .MOTOR_CTRL(MOTOR_CTRL), 263 | `else 264 | .UART_CTS(1'b0), 265 | `endif 266 | .UART_RX(UART_RX), 267 | .UART_TX(UART_TX) 268 | ); 269 | endmodule 270 | -------------------------------------------------------------------------------- /rtl/mist/cyc3/rom_reconfig_pal.vhd: -------------------------------------------------------------------------------- 1 | -- megafunction wizard: %ROM: 1-PORT% 2 | -- GENERATION: STANDARD 3 | -- VERSION: WM1.0 4 | -- MODULE: altsyncram 5 | 6 | -- ============================================================ 7 | -- File Name: rom_reconfig_pal.vhd 8 | -- Megafunction Name(s): 9 | -- altsyncram 10 | -- 11 | -- Simulation Library Files(s): 12 | -- altera_mf 13 | -- ============================================================ 14 | -- ************************************************************ 15 | -- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! 16 | -- 17 | -- 13.1.4 Build 182 03/12/2014 SJ Web Edition 18 | -- ************************************************************ 19 | 20 | 21 | --Copyright (C) 1991-2014 Altera Corporation 22 | --Your use of Altera Corporation's design tools, logic functions 23 | --and other software and tools, and its AMPP partner logic 24 | --functions, and any output files from any of the foregoing 25 | --(including device programming or simulation files), and any 26 | --associated documentation or information are expressly subject 27 | --to the terms and conditions of the Altera Program License 28 | --Subscription Agreement, Altera MegaCore Function License 29 | --Agreement, or other applicable license agreement, including, 30 | --without limitation, that your use is for the sole purpose of 31 | --programming logic devices manufactured by Altera and sold by 32 | --Altera or its authorized distributors. Please refer to the 33 | --applicable agreement for further details. 34 | 35 | 36 | LIBRARY ieee; 37 | USE ieee.std_logic_1164.all; 38 | 39 | LIBRARY altera_mf; 40 | USE altera_mf.altera_mf_components.all; 41 | 42 | ENTITY rom_reconfig_pal IS 43 | PORT 44 | ( 45 | address : IN STD_LOGIC_VECTOR (7 DOWNTO 0); 46 | clock : IN STD_LOGIC := '1'; 47 | rden : IN STD_LOGIC := '1'; 48 | q : OUT STD_LOGIC_VECTOR (0 DOWNTO 0) 49 | ); 50 | END rom_reconfig_pal; 51 | 52 | 53 | ARCHITECTURE SYN OF rom_reconfig_pal IS 54 | 55 | SIGNAL sub_wire0 : STD_LOGIC_VECTOR (0 DOWNTO 0); 56 | 57 | BEGIN 58 | q <= sub_wire0(0 DOWNTO 0); 59 | 60 | altsyncram_component : altsyncram 61 | GENERIC MAP ( 62 | address_aclr_a => "NONE", 63 | clock_enable_input_a => "BYPASS", 64 | clock_enable_output_a => "BYPASS", 65 | init_file => "./rtl/mist/cyc3/pll_c64_pal.mif", 66 | intended_device_family => "Cyclone III", 67 | lpm_hint => "ENABLE_RUNTIME_MOD=NO", 68 | lpm_type => "altsyncram", 69 | numwords_a => 256, 70 | operation_mode => "ROM", 71 | outdata_aclr_a => "NONE", 72 | outdata_reg_a => "CLOCK0", 73 | widthad_a => 8, 74 | width_a => 1, 75 | width_byteena_a => 1 76 | ) 77 | PORT MAP ( 78 | address_a => address, 79 | clock0 => clock, 80 | rden_a => rden, 81 | q_a => sub_wire0 82 | ); 83 | 84 | 85 | 86 | END SYN; 87 | 88 | -- ============================================================ 89 | -- CNX file retrieval info 90 | -- ============================================================ 91 | -- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" 92 | -- Retrieval info: PRIVATE: AclrAddr NUMERIC "0" 93 | -- Retrieval info: PRIVATE: AclrByte NUMERIC "0" 94 | -- Retrieval info: PRIVATE: AclrOutput NUMERIC "0" 95 | -- Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0" 96 | -- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" 97 | -- Retrieval info: PRIVATE: BlankMemory NUMERIC "0" 98 | -- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" 99 | -- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" 100 | -- Retrieval info: PRIVATE: Clken NUMERIC "0" 101 | -- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" 102 | -- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A" 103 | -- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" 104 | -- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III" 105 | -- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" 106 | -- Retrieval info: PRIVATE: JTAG_ID STRING "NONE" 107 | -- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" 108 | -- Retrieval info: PRIVATE: MIFfilename STRING "pll_c64_pal.mif" 109 | -- Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "256" 110 | -- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" 111 | -- Retrieval info: PRIVATE: RegAddr NUMERIC "1" 112 | -- Retrieval info: PRIVATE: RegOutput NUMERIC "1" 113 | -- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" 114 | -- Retrieval info: PRIVATE: SingleClock NUMERIC "1" 115 | -- Retrieval info: PRIVATE: UseDQRAM NUMERIC "0" 116 | -- Retrieval info: PRIVATE: WidthAddr NUMERIC "8" 117 | -- Retrieval info: PRIVATE: WidthData NUMERIC "1" 118 | -- Retrieval info: PRIVATE: rden NUMERIC "1" 119 | -- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all 120 | -- Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE" 121 | -- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" 122 | -- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS" 123 | -- Retrieval info: CONSTANT: INIT_FILE STRING "pll_c64_pal.mif" 124 | -- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" 125 | -- Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO" 126 | -- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" 127 | -- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "256" 128 | -- Retrieval info: CONSTANT: OPERATION_MODE STRING "ROM" 129 | -- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE" 130 | -- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0" 131 | -- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "8" 132 | -- Retrieval info: CONSTANT: WIDTH_A NUMERIC "1" 133 | -- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" 134 | -- Retrieval info: USED_PORT: address 0 0 8 0 INPUT NODEFVAL "address[7..0]" 135 | -- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" 136 | -- Retrieval info: USED_PORT: q 0 0 1 0 OUTPUT NODEFVAL "q[0..0]" 137 | -- Retrieval info: USED_PORT: rden 0 0 0 0 INPUT VCC "rden" 138 | -- Retrieval info: CONNECT: @address_a 0 0 8 0 address 0 0 8 0 139 | -- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 140 | -- Retrieval info: CONNECT: @rden_a 0 0 0 0 rden 0 0 0 0 141 | -- Retrieval info: CONNECT: q 0 0 1 0 @q_a 0 0 1 0 142 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_pal.vhd TRUE 143 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_pal.inc FALSE 144 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_pal.cmp FALSE 145 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_pal.bsf FALSE 146 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_pal_inst.vhd FALSE 147 | -- Retrieval info: LIB_FILE: altera_mf 148 | -------------------------------------------------------------------------------- /rtl/mist/cyc3/rom_reconfig_ntsc.vhd: -------------------------------------------------------------------------------- 1 | -- megafunction wizard: %ROM: 1-PORT% 2 | -- GENERATION: STANDARD 3 | -- VERSION: WM1.0 4 | -- MODULE: altsyncram 5 | 6 | -- ============================================================ 7 | -- File Name: rom_reconfig_ntsc.vhd 8 | -- Megafunction Name(s): 9 | -- altsyncram 10 | -- 11 | -- Simulation Library Files(s): 12 | -- altera_mf 13 | -- ============================================================ 14 | -- ************************************************************ 15 | -- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! 16 | -- 17 | -- 13.1.4 Build 182 03/12/2014 SJ Web Edition 18 | -- ************************************************************ 19 | 20 | 21 | --Copyright (C) 1991-2014 Altera Corporation 22 | --Your use of Altera Corporation's design tools, logic functions 23 | --and other software and tools, and its AMPP partner logic 24 | --functions, and any output files from any of the foregoing 25 | --(including device programming or simulation files), and any 26 | --associated documentation or information are expressly subject 27 | --to the terms and conditions of the Altera Program License 28 | --Subscription Agreement, Altera MegaCore Function License 29 | --Agreement, or other applicable license agreement, including, 30 | --without limitation, that your use is for the sole purpose of 31 | --programming logic devices manufactured by Altera and sold by 32 | --Altera or its authorized distributors. Please refer to the 33 | --applicable agreement for further details. 34 | 35 | 36 | LIBRARY ieee; 37 | USE ieee.std_logic_1164.all; 38 | 39 | LIBRARY altera_mf; 40 | USE altera_mf.altera_mf_components.all; 41 | 42 | ENTITY rom_reconfig_ntsc IS 43 | PORT 44 | ( 45 | address : IN STD_LOGIC_VECTOR (7 DOWNTO 0); 46 | clock : IN STD_LOGIC := '1'; 47 | rden : IN STD_LOGIC := '1'; 48 | q : OUT STD_LOGIC_VECTOR (0 DOWNTO 0) 49 | ); 50 | END rom_reconfig_ntsc; 51 | 52 | 53 | ARCHITECTURE SYN OF rom_reconfig_ntsc IS 54 | 55 | SIGNAL sub_wire0 : STD_LOGIC_VECTOR (0 DOWNTO 0); 56 | 57 | BEGIN 58 | q <= sub_wire0(0 DOWNTO 0); 59 | 60 | altsyncram_component : altsyncram 61 | GENERIC MAP ( 62 | address_aclr_a => "NONE", 63 | clock_enable_input_a => "BYPASS", 64 | clock_enable_output_a => "BYPASS", 65 | init_file => "./rtl/mist/cyc3/pll_c64_ntsc.mif", 66 | intended_device_family => "Cyclone III", 67 | lpm_hint => "ENABLE_RUNTIME_MOD=NO", 68 | lpm_type => "altsyncram", 69 | numwords_a => 256, 70 | operation_mode => "ROM", 71 | outdata_aclr_a => "NONE", 72 | outdata_reg_a => "CLOCK0", 73 | widthad_a => 8, 74 | width_a => 1, 75 | width_byteena_a => 1 76 | ) 77 | PORT MAP ( 78 | address_a => address, 79 | clock0 => clock, 80 | rden_a => rden, 81 | q_a => sub_wire0 82 | ); 83 | 84 | 85 | 86 | END SYN; 87 | 88 | -- ============================================================ 89 | -- CNX file retrieval info 90 | -- ============================================================ 91 | -- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" 92 | -- Retrieval info: PRIVATE: AclrAddr NUMERIC "0" 93 | -- Retrieval info: PRIVATE: AclrByte NUMERIC "0" 94 | -- Retrieval info: PRIVATE: AclrOutput NUMERIC "0" 95 | -- Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0" 96 | -- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" 97 | -- Retrieval info: PRIVATE: BlankMemory NUMERIC "0" 98 | -- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" 99 | -- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" 100 | -- Retrieval info: PRIVATE: Clken NUMERIC "0" 101 | -- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" 102 | -- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A" 103 | -- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" 104 | -- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III" 105 | -- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" 106 | -- Retrieval info: PRIVATE: JTAG_ID STRING "NONE" 107 | -- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" 108 | -- Retrieval info: PRIVATE: MIFfilename STRING "pll_c64_ntsc.mif" 109 | -- Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "256" 110 | -- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" 111 | -- Retrieval info: PRIVATE: RegAddr NUMERIC "1" 112 | -- Retrieval info: PRIVATE: RegOutput NUMERIC "1" 113 | -- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" 114 | -- Retrieval info: PRIVATE: SingleClock NUMERIC "1" 115 | -- Retrieval info: PRIVATE: UseDQRAM NUMERIC "0" 116 | -- Retrieval info: PRIVATE: WidthAddr NUMERIC "8" 117 | -- Retrieval info: PRIVATE: WidthData NUMERIC "1" 118 | -- Retrieval info: PRIVATE: rden NUMERIC "1" 119 | -- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all 120 | -- Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE" 121 | -- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" 122 | -- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS" 123 | -- Retrieval info: CONSTANT: INIT_FILE STRING "pll_c64_ntsc.mif" 124 | -- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" 125 | -- Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO" 126 | -- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" 127 | -- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "256" 128 | -- Retrieval info: CONSTANT: OPERATION_MODE STRING "ROM" 129 | -- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE" 130 | -- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0" 131 | -- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "8" 132 | -- Retrieval info: CONSTANT: WIDTH_A NUMERIC "1" 133 | -- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" 134 | -- Retrieval info: USED_PORT: address 0 0 8 0 INPUT NODEFVAL "address[7..0]" 135 | -- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" 136 | -- Retrieval info: USED_PORT: q 0 0 1 0 OUTPUT NODEFVAL "q[0..0]" 137 | -- Retrieval info: USED_PORT: rden 0 0 0 0 INPUT VCC "rden" 138 | -- Retrieval info: CONNECT: @address_a 0 0 8 0 address 0 0 8 0 139 | -- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 140 | -- Retrieval info: CONNECT: @rden_a 0 0 0 0 rden 0 0 0 0 141 | -- Retrieval info: CONNECT: q 0 0 1 0 @q_a 0 0 1 0 142 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_ntsc.vhd TRUE 143 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_ntsc.inc FALSE 144 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_ntsc.cmp FALSE 145 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_ntsc.bsf FALSE 146 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_ntsc_inst.vhd FALSE 147 | -- Retrieval info: LIB_FILE: altera_mf 148 | -------------------------------------------------------------------------------- /rtl/mist/cyc4gx/rom_reconfig_pal.vhd: -------------------------------------------------------------------------------- 1 | -- megafunction wizard: %ROM: 1-PORT% 2 | -- GENERATION: STANDARD 3 | -- VERSION: WM1.0 4 | -- MODULE: altsyncram 5 | 6 | -- ============================================================ 7 | -- File Name: rom_reconfig_pal.vhd 8 | -- Megafunction Name(s): 9 | -- altsyncram 10 | -- 11 | -- Simulation Library Files(s): 12 | -- altera_mf 13 | -- ============================================================ 14 | -- ************************************************************ 15 | -- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! 16 | -- 17 | -- 21.1.1 Build 850 06/23/2022 SJ Standard Edition 18 | -- ************************************************************ 19 | 20 | 21 | --Copyright (C) 2022 Intel Corporation. All rights reserved. 22 | --Your use of Intel Corporation's design tools, logic functions 23 | --and other software and tools, and any partner logic 24 | --functions, and any output files from any of the foregoing 25 | --(including device programming or simulation files), and any 26 | --associated documentation or information are expressly subject 27 | --to the terms and conditions of the Intel Program License 28 | --Subscription Agreement, the Intel Quartus Prime License Agreement, 29 | --the Intel FPGA IP License Agreement, or other applicable license 30 | --agreement, including, without limitation, that your use is for 31 | --the sole purpose of programming logic devices manufactured by 32 | --Intel and sold by Intel or its authorized distributors. Please 33 | --refer to the applicable agreement for further details, at 34 | --https://fpgasoftware.intel.com/eula. 35 | 36 | 37 | LIBRARY ieee; 38 | USE ieee.std_logic_1164.all; 39 | 40 | LIBRARY altera_mf; 41 | USE altera_mf.altera_mf_components.all; 42 | 43 | ENTITY rom_reconfig_pal IS 44 | PORT 45 | ( 46 | address : IN STD_LOGIC_VECTOR (7 DOWNTO 0); 47 | clock : IN STD_LOGIC := '1'; 48 | rden : IN STD_LOGIC := '1'; 49 | q : OUT STD_LOGIC_VECTOR (0 DOWNTO 0) 50 | ); 51 | END rom_reconfig_pal; 52 | 53 | 54 | ARCHITECTURE SYN OF rom_reconfig_pal IS 55 | 56 | SIGNAL sub_wire0 : STD_LOGIC_VECTOR (0 DOWNTO 0); 57 | 58 | BEGIN 59 | q <= sub_wire0(0 DOWNTO 0); 60 | 61 | altsyncram_component : altsyncram 62 | GENERIC MAP ( 63 | address_aclr_a => "NONE", 64 | clock_enable_input_a => "BYPASS", 65 | clock_enable_output_a => "BYPASS", 66 | init_file => "./rtl/mist/cyc4gx/pll_c64_pal.mif", 67 | intended_device_family => "Cyclone IV GX", 68 | lpm_hint => "ENABLE_RUNTIME_MOD=NO", 69 | lpm_type => "altsyncram", 70 | numwords_a => 256, 71 | operation_mode => "ROM", 72 | outdata_aclr_a => "NONE", 73 | outdata_reg_a => "CLOCK0", 74 | widthad_a => 8, 75 | width_a => 1, 76 | width_byteena_a => 1 77 | ) 78 | PORT MAP ( 79 | address_a => address, 80 | clock0 => clock, 81 | rden_a => rden, 82 | q_a => sub_wire0 83 | ); 84 | 85 | 86 | 87 | END SYN; 88 | 89 | -- ============================================================ 90 | -- CNX file retrieval info 91 | -- ============================================================ 92 | -- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" 93 | -- Retrieval info: PRIVATE: AclrAddr NUMERIC "0" 94 | -- Retrieval info: PRIVATE: AclrByte NUMERIC "0" 95 | -- Retrieval info: PRIVATE: AclrOutput NUMERIC "0" 96 | -- Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0" 97 | -- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" 98 | -- Retrieval info: PRIVATE: BlankMemory NUMERIC "0" 99 | -- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" 100 | -- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" 101 | -- Retrieval info: PRIVATE: Clken NUMERIC "0" 102 | -- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" 103 | -- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A" 104 | -- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" 105 | -- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV GX" 106 | -- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" 107 | -- Retrieval info: PRIVATE: JTAG_ID STRING "NONE" 108 | -- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" 109 | -- Retrieval info: PRIVATE: MIFfilename STRING "./rtl/mist/pll_c64_pal.mif" 110 | -- Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "256" 111 | -- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" 112 | -- Retrieval info: PRIVATE: RegAddr NUMERIC "1" 113 | -- Retrieval info: PRIVATE: RegOutput NUMERIC "1" 114 | -- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" 115 | -- Retrieval info: PRIVATE: SingleClock NUMERIC "1" 116 | -- Retrieval info: PRIVATE: UseDQRAM NUMERIC "0" 117 | -- Retrieval info: PRIVATE: WidthAddr NUMERIC "8" 118 | -- Retrieval info: PRIVATE: WidthData NUMERIC "1" 119 | -- Retrieval info: PRIVATE: rden NUMERIC "1" 120 | -- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all 121 | -- Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE" 122 | -- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" 123 | -- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS" 124 | -- Retrieval info: CONSTANT: INIT_FILE STRING "./rtl/mist/pll_c64_pal.mif" 125 | -- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV GX" 126 | -- Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO" 127 | -- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" 128 | -- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "256" 129 | -- Retrieval info: CONSTANT: OPERATION_MODE STRING "ROM" 130 | -- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE" 131 | -- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0" 132 | -- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "8" 133 | -- Retrieval info: CONSTANT: WIDTH_A NUMERIC "1" 134 | -- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" 135 | -- Retrieval info: USED_PORT: address 0 0 8 0 INPUT NODEFVAL "address[7..0]" 136 | -- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" 137 | -- Retrieval info: USED_PORT: q 0 0 1 0 OUTPUT NODEFVAL "q[0..0]" 138 | -- Retrieval info: USED_PORT: rden 0 0 0 0 INPUT VCC "rden" 139 | -- Retrieval info: CONNECT: @address_a 0 0 8 0 address 0 0 8 0 140 | -- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 141 | -- Retrieval info: CONNECT: @rden_a 0 0 0 0 rden 0 0 0 0 142 | -- Retrieval info: CONNECT: q 0 0 1 0 @q_a 0 0 1 0 143 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_pal.vhd TRUE 144 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_pal.inc FALSE 145 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_pal.cmp FALSE 146 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_pal.bsf FALSE 147 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_pal_inst.vhd FALSE 148 | -- Retrieval info: LIB_FILE: altera_mf 149 | -------------------------------------------------------------------------------- /rtl/mist/cyc4gx/rom_reconfig_ntsc.vhd: -------------------------------------------------------------------------------- 1 | -- megafunction wizard: %ROM: 1-PORT% 2 | -- GENERATION: STANDARD 3 | -- VERSION: WM1.0 4 | -- MODULE: altsyncram 5 | 6 | -- ============================================================ 7 | -- File Name: rom_reconfig_ntsc.vhd 8 | -- Megafunction Name(s): 9 | -- altsyncram 10 | -- 11 | -- Simulation Library Files(s): 12 | -- altera_mf 13 | -- ============================================================ 14 | -- ************************************************************ 15 | -- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! 16 | -- 17 | -- 21.1.1 Build 850 06/23/2022 SJ Standard Edition 18 | -- ************************************************************ 19 | 20 | 21 | --Copyright (C) 2022 Intel Corporation. All rights reserved. 22 | --Your use of Intel Corporation's design tools, logic functions 23 | --and other software and tools, and any partner logic 24 | --functions, and any output files from any of the foregoing 25 | --(including device programming or simulation files), and any 26 | --associated documentation or information are expressly subject 27 | --to the terms and conditions of the Intel Program License 28 | --Subscription Agreement, the Intel Quartus Prime License Agreement, 29 | --the Intel FPGA IP License Agreement, or other applicable license 30 | --agreement, including, without limitation, that your use is for 31 | --the sole purpose of programming logic devices manufactured by 32 | --Intel and sold by Intel or its authorized distributors. Please 33 | --refer to the applicable agreement for further details, at 34 | --https://fpgasoftware.intel.com/eula. 35 | 36 | 37 | LIBRARY ieee; 38 | USE ieee.std_logic_1164.all; 39 | 40 | LIBRARY altera_mf; 41 | USE altera_mf.altera_mf_components.all; 42 | 43 | ENTITY rom_reconfig_ntsc IS 44 | PORT 45 | ( 46 | address : IN STD_LOGIC_VECTOR (7 DOWNTO 0); 47 | clock : IN STD_LOGIC := '1'; 48 | rden : IN STD_LOGIC := '1'; 49 | q : OUT STD_LOGIC_VECTOR (0 DOWNTO 0) 50 | ); 51 | END rom_reconfig_ntsc; 52 | 53 | 54 | ARCHITECTURE SYN OF rom_reconfig_ntsc IS 55 | 56 | SIGNAL sub_wire0 : STD_LOGIC_VECTOR (0 DOWNTO 0); 57 | 58 | BEGIN 59 | q <= sub_wire0(0 DOWNTO 0); 60 | 61 | altsyncram_component : altsyncram 62 | GENERIC MAP ( 63 | address_aclr_a => "NONE", 64 | clock_enable_input_a => "BYPASS", 65 | clock_enable_output_a => "BYPASS", 66 | init_file => "./rtl/mist/cyc4gx/pll_c64_ntsc.mif", 67 | intended_device_family => "Cyclone IV GX", 68 | lpm_hint => "ENABLE_RUNTIME_MOD=NO", 69 | lpm_type => "altsyncram", 70 | numwords_a => 256, 71 | operation_mode => "ROM", 72 | outdata_aclr_a => "NONE", 73 | outdata_reg_a => "CLOCK0", 74 | widthad_a => 8, 75 | width_a => 1, 76 | width_byteena_a => 1 77 | ) 78 | PORT MAP ( 79 | address_a => address, 80 | clock0 => clock, 81 | rden_a => rden, 82 | q_a => sub_wire0 83 | ); 84 | 85 | 86 | 87 | END SYN; 88 | 89 | -- ============================================================ 90 | -- CNX file retrieval info 91 | -- ============================================================ 92 | -- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" 93 | -- Retrieval info: PRIVATE: AclrAddr NUMERIC "0" 94 | -- Retrieval info: PRIVATE: AclrByte NUMERIC "0" 95 | -- Retrieval info: PRIVATE: AclrOutput NUMERIC "0" 96 | -- Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0" 97 | -- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" 98 | -- Retrieval info: PRIVATE: BlankMemory NUMERIC "0" 99 | -- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" 100 | -- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" 101 | -- Retrieval info: PRIVATE: Clken NUMERIC "0" 102 | -- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" 103 | -- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A" 104 | -- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" 105 | -- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV GX" 106 | -- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" 107 | -- Retrieval info: PRIVATE: JTAG_ID STRING "NONE" 108 | -- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" 109 | -- Retrieval info: PRIVATE: MIFfilename STRING "./rtl/mist/pll_c64_ntsc.mif" 110 | -- Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "256" 111 | -- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" 112 | -- Retrieval info: PRIVATE: RegAddr NUMERIC "1" 113 | -- Retrieval info: PRIVATE: RegOutput NUMERIC "1" 114 | -- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" 115 | -- Retrieval info: PRIVATE: SingleClock NUMERIC "1" 116 | -- Retrieval info: PRIVATE: UseDQRAM NUMERIC "0" 117 | -- Retrieval info: PRIVATE: WidthAddr NUMERIC "8" 118 | -- Retrieval info: PRIVATE: WidthData NUMERIC "1" 119 | -- Retrieval info: PRIVATE: rden NUMERIC "1" 120 | -- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all 121 | -- Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE" 122 | -- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" 123 | -- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS" 124 | -- Retrieval info: CONSTANT: INIT_FILE STRING "./rtl/mist/pll_c64_ntsc.mif" 125 | -- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV GX" 126 | -- Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO" 127 | -- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" 128 | -- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "256" 129 | -- Retrieval info: CONSTANT: OPERATION_MODE STRING "ROM" 130 | -- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE" 131 | -- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0" 132 | -- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "8" 133 | -- Retrieval info: CONSTANT: WIDTH_A NUMERIC "1" 134 | -- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" 135 | -- Retrieval info: USED_PORT: address 0 0 8 0 INPUT NODEFVAL "address[7..0]" 136 | -- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" 137 | -- Retrieval info: USED_PORT: q 0 0 1 0 OUTPUT NODEFVAL "q[0..0]" 138 | -- Retrieval info: USED_PORT: rden 0 0 0 0 INPUT VCC "rden" 139 | -- Retrieval info: CONNECT: @address_a 0 0 8 0 address 0 0 8 0 140 | -- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 141 | -- Retrieval info: CONNECT: @rden_a 0 0 0 0 rden 0 0 0 0 142 | -- Retrieval info: CONNECT: q 0 0 1 0 @q_a 0 0 1 0 143 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_ntsc.vhd TRUE 144 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_ntsc.inc FALSE 145 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_ntsc.cmp FALSE 146 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_ntsc.bsf FALSE 147 | -- Retrieval info: GEN_FILE: TYPE_NORMAL rom_reconfig_ntsc_inst.vhd FALSE 148 | -- Retrieval info: LIB_FILE: altera_mf 149 | -------------------------------------------------------------------------------- /rtl/sid8580/sid_envelope.v: -------------------------------------------------------------------------------- 1 | module sid_envelope (clock, reset, gate, att_dec, sus_rel, envelope); 2 | 3 | // Input Signals 4 | input wire [ 0:0] clock; 5 | input wire [ 0:0] reset; 6 | input wire [ 0:0] gate; 7 | input wire [ 7:0] att_dec; 8 | input wire [ 7:0] sus_rel; 9 | 10 | // Output Signals 11 | output reg [7:0] envelope; 12 | 13 | // Internal Signals 14 | reg [ 1:0] state; 15 | reg [ 0:0] gate_edge; 16 | reg [14:0] rate_counter; 17 | reg [14:0] rate_period; 18 | wire [14:0] adsrtable [0:15]; 19 | reg [ 7:0] exponential_counter; 20 | reg [ 7:0] exponential_counter_period; 21 | reg [ 0:0] hold_zero; 22 | reg [ 0:0] envelope_pipeline; 23 | 24 | `define ST_ATTACK 2'b00 25 | `define ST_DEC_SUS 2'b01 26 | `define ST_RELEASE 2'b10 27 | 28 | assign adsrtable[4'h0] = 15'h007f; 29 | assign adsrtable[4'h1] = 15'h3000; 30 | assign adsrtable[4'h2] = 15'h1e00; 31 | assign adsrtable[4'h3] = 15'h0660; 32 | assign adsrtable[4'h4] = 15'h0182; 33 | assign adsrtable[4'h5] = 15'h5573; 34 | assign adsrtable[4'h6] = 15'h000e; 35 | assign adsrtable[4'h7] = 15'h3805; 36 | assign adsrtable[4'h8] = 15'h2424; 37 | assign adsrtable[4'h9] = 15'h2220; 38 | assign adsrtable[4'ha] = 15'h090c; 39 | assign adsrtable[4'hb] = 15'h0ecd; 40 | assign adsrtable[4'hc] = 15'h010e; 41 | assign adsrtable[4'hd] = 15'h23f7; 42 | assign adsrtable[4'he] = 15'h5237; 43 | assign adsrtable[4'hf] = 15'h64a8; 44 | 45 | // State Logic 46 | always @(posedge clock) 47 | begin 48 | if (reset) 49 | state <= `ST_RELEASE; 50 | else 51 | begin 52 | if (gate_edge != gate) 53 | if (gate) 54 | state <= `ST_ATTACK; 55 | else 56 | state <= `ST_RELEASE; 57 | if (((rate_counter == rate_period) && 58 | (state == `ST_ATTACK || 59 | (exponential_counter + 1'b1) == exponential_counter_period) && 60 | (!hold_zero))) 61 | case (state) 62 | `ST_ATTACK: 63 | if (envelope + 1'b1 == 8'hff) 64 | state <= `ST_DEC_SUS; 65 | default: 66 | ; 67 | endcase 68 | end 69 | end 70 | 71 | // Gate Switch Detection 72 | always @(posedge clock) 73 | begin 74 | if (reset) 75 | gate_edge <= 1'b0; 76 | else 77 | if (gate_edge != gate) 78 | gate_edge <= gate; 79 | end 80 | 81 | // Envelope 82 | always @(posedge clock) 83 | begin 84 | if (reset) 85 | envelope <= 8'h00; 86 | else 87 | begin 88 | if (envelope_pipeline) 89 | envelope <= envelope - 1'b1; 90 | if (((rate_counter == rate_period) && 91 | (state == `ST_ATTACK || 92 | (exponential_counter + 1'b1) == exponential_counter_period) && 93 | (!hold_zero))) 94 | case (state) 95 | `ST_ATTACK: 96 | envelope <= envelope + 1'b1; 97 | `ST_DEC_SUS: 98 | if (envelope != {2{sus_rel[7:4]}} && 99 | exponential_counter_period == 1) 100 | envelope <= envelope - 1'b1; 101 | `ST_RELEASE: 102 | if (exponential_counter_period == 1) 103 | envelope <= envelope - 1'b1; 104 | endcase 105 | end 106 | end 107 | 108 | // Envelope Pipeline 109 | always @(posedge clock) 110 | begin 111 | if (reset) 112 | envelope_pipeline <= 1'b0; 113 | else 114 | begin 115 | if (gate_edge != gate) 116 | if (gate) 117 | envelope_pipeline <= 1'b0; 118 | if (envelope_pipeline) 119 | envelope_pipeline <= 1'b0; 120 | if (((rate_counter == rate_period) && 121 | (state == `ST_ATTACK || 122 | (exponential_counter + 1'b1) == exponential_counter_period) && 123 | (!hold_zero))) 124 | case (state) 125 | `ST_DEC_SUS: 126 | if (envelope != {2{sus_rel[7:4]}} && 127 | exponential_counter_period != 1) 128 | envelope_pipeline <= 1'b1; 129 | `ST_RELEASE: 130 | if(exponential_counter_period != 1) 131 | envelope_pipeline <= 1'b1; 132 | default: 133 | ; 134 | endcase 135 | end 136 | end 137 | 138 | // Exponential Counter 139 | always @(posedge clock) 140 | begin 141 | if (reset) 142 | exponential_counter <= 8'h00; 143 | else 144 | begin 145 | if (rate_counter == rate_period) 146 | begin 147 | exponential_counter <= exponential_counter + 1'b1; 148 | if (state == `ST_ATTACK || 149 | (exponential_counter + 1'b1) == exponential_counter_period) 150 | exponential_counter <= 8'h00; 151 | end 152 | end 153 | end 154 | 155 | // Exponential Counter Period 156 | always @(posedge clock) 157 | begin 158 | if (reset) 159 | begin 160 | hold_zero <= 1'b1; 161 | exponential_counter_period <= 8'h00; 162 | end 163 | else 164 | begin 165 | if (gate_edge != gate) 166 | if (gate) 167 | hold_zero <= 1'b0; 168 | if ((envelope_pipeline) || ((rate_counter == rate_period) && 169 | (state == `ST_ATTACK || 170 | (exponential_counter + 1'b1) == exponential_counter_period) && 171 | (!hold_zero))) 172 | begin 173 | case (state == `ST_ATTACK ? envelope + 1'b1 : envelope - 1'b1) 174 | 8'hff: 175 | exponential_counter_period <= 8'd1; 176 | 8'h5d: 177 | exponential_counter_period <= 8'd2; 178 | 8'h36: 179 | exponential_counter_period <= 8'd4; 180 | 8'h1a: 181 | exponential_counter_period <= 8'd8; 182 | 8'h0e: 183 | exponential_counter_period <= 8'd16; 184 | 8'h06: 185 | exponential_counter_period <= 8'd30; 186 | 8'h00: 187 | begin 188 | exponential_counter_period <= 8'd1; 189 | hold_zero <= 1'b1; 190 | end 191 | default: 192 | ; 193 | endcase 194 | end 195 | end 196 | end 197 | 198 | // Rate Counter 199 | always @(posedge clock) 200 | begin 201 | if (reset || rate_counter == rate_period) 202 | rate_counter <= 15'h7fff; 203 | else 204 | rate_counter <= {rate_counter[1] ^ rate_counter[0], rate_counter[14:1]}; 205 | end 206 | 207 | // Rate Period 208 | always @(posedge clock) 209 | begin 210 | if (reset) 211 | rate_period <= adsrtable[sus_rel[3:0]]; 212 | else 213 | begin 214 | if (gate_edge != gate) 215 | begin 216 | if (gate) 217 | rate_period <= adsrtable[att_dec[7:4]]; 218 | else 219 | rate_period <= adsrtable[sus_rel[3:0]]; 220 | end 221 | case (state) 222 | `ST_ATTACK: 223 | rate_period <= adsrtable[att_dec[7:4]]; 224 | `ST_DEC_SUS: 225 | rate_period <= adsrtable[att_dec[3:0]]; 226 | default: 227 | rate_period <= adsrtable[sus_rel[3:0]]; 228 | endcase 229 | end 230 | end 231 | 232 | endmodule 233 | -------------------------------------------------------------------------------- /rtl/tap_fifo.vhd: -------------------------------------------------------------------------------- 1 | -- megafunction wizard: %FIFO% 2 | -- GENERATION: STANDARD 3 | -- VERSION: WM1.0 4 | -- MODULE: scfifo 5 | 6 | -- ============================================================ 7 | -- File Name: tap_fifo.vhd 8 | -- Megafunction Name(s): 9 | -- scfifo 10 | -- 11 | -- Simulation Library Files(s): 12 | -- altera_mf 13 | -- ============================================================ 14 | -- ************************************************************ 15 | -- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! 16 | -- 17 | -- 13.1.4 Build 182 03/12/2014 SJ Web Edition 18 | -- ************************************************************ 19 | 20 | 21 | --Copyright (C) 1991-2014 Altera Corporation 22 | --Your use of Altera Corporation's design tools, logic functions 23 | --and other software and tools, and its AMPP partner logic 24 | --functions, and any output files from any of the foregoing 25 | --(including device programming or simulation files), and any 26 | --associated documentation or information are expressly subject 27 | --to the terms and conditions of the Altera Program License 28 | --Subscription Agreement, Altera MegaCore Function License 29 | --Agreement, or other applicable license agreement, including, 30 | --without limitation, that your use is for the sole purpose of 31 | --programming logic devices manufactured by Altera and sold by 32 | --Altera or its authorized distributors. Please refer to the 33 | --applicable agreement for further details. 34 | 35 | 36 | LIBRARY ieee; 37 | USE ieee.std_logic_1164.all; 38 | 39 | LIBRARY altera_mf; 40 | USE altera_mf.all; 41 | 42 | ENTITY tap_fifo IS 43 | PORT 44 | ( 45 | aclr : IN STD_LOGIC ; 46 | clock : IN STD_LOGIC ; 47 | data : IN STD_LOGIC_VECTOR (7 DOWNTO 0); 48 | rdreq : IN STD_LOGIC ; 49 | wrreq : IN STD_LOGIC ; 50 | empty : OUT STD_LOGIC ; 51 | full : OUT STD_LOGIC ; 52 | q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) 53 | ); 54 | END tap_fifo; 55 | 56 | 57 | ARCHITECTURE SYN OF tap_fifo IS 58 | 59 | SIGNAL sub_wire0 : STD_LOGIC ; 60 | SIGNAL sub_wire1 : STD_LOGIC ; 61 | SIGNAL sub_wire2 : STD_LOGIC_VECTOR (7 DOWNTO 0); 62 | 63 | 64 | 65 | COMPONENT scfifo 66 | GENERIC ( 67 | add_ram_output_register : STRING; 68 | intended_device_family : STRING; 69 | lpm_numwords : NATURAL; 70 | lpm_showahead : STRING; 71 | lpm_type : STRING; 72 | lpm_width : NATURAL; 73 | lpm_widthu : NATURAL; 74 | overflow_checking : STRING; 75 | underflow_checking : STRING; 76 | use_eab : STRING 77 | ); 78 | PORT ( 79 | aclr : IN STD_LOGIC ; 80 | clock : IN STD_LOGIC ; 81 | data : IN STD_LOGIC_VECTOR (7 DOWNTO 0); 82 | rdreq : IN STD_LOGIC ; 83 | empty : OUT STD_LOGIC ; 84 | full : OUT STD_LOGIC ; 85 | q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0); 86 | wrreq : IN STD_LOGIC 87 | ); 88 | END COMPONENT; 89 | 90 | BEGIN 91 | empty <= sub_wire0; 92 | full <= sub_wire1; 93 | q <= sub_wire2(7 DOWNTO 0); 94 | 95 | scfifo_component : scfifo 96 | GENERIC MAP ( 97 | add_ram_output_register => "OFF", 98 | intended_device_family => "Cyclone III", 99 | lpm_numwords => 64, 100 | lpm_showahead => "OFF", 101 | lpm_type => "scfifo", 102 | lpm_width => 8, 103 | lpm_widthu => 6, 104 | overflow_checking => "ON", 105 | underflow_checking => "ON", 106 | use_eab => "ON" 107 | ) 108 | PORT MAP ( 109 | aclr => aclr, 110 | clock => clock, 111 | data => data, 112 | rdreq => rdreq, 113 | wrreq => wrreq, 114 | empty => sub_wire0, 115 | full => sub_wire1, 116 | q => sub_wire2 117 | ); 118 | 119 | 120 | 121 | END SYN; 122 | 123 | -- ============================================================ 124 | -- CNX file retrieval info 125 | -- ============================================================ 126 | -- Retrieval info: PRIVATE: AlmostEmpty NUMERIC "0" 127 | -- Retrieval info: PRIVATE: AlmostEmptyThr NUMERIC "-1" 128 | -- Retrieval info: PRIVATE: AlmostFull NUMERIC "0" 129 | -- Retrieval info: PRIVATE: AlmostFullThr NUMERIC "-1" 130 | -- Retrieval info: PRIVATE: CLOCKS_ARE_SYNCHRONIZED NUMERIC "0" 131 | -- Retrieval info: PRIVATE: Clock NUMERIC "0" 132 | -- Retrieval info: PRIVATE: Depth NUMERIC "64" 133 | -- Retrieval info: PRIVATE: Empty NUMERIC "1" 134 | -- Retrieval info: PRIVATE: Full NUMERIC "1" 135 | -- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III" 136 | -- Retrieval info: PRIVATE: LE_BasedFIFO NUMERIC "0" 137 | -- Retrieval info: PRIVATE: LegacyRREQ NUMERIC "1" 138 | -- Retrieval info: PRIVATE: MAX_DEPTH_BY_9 NUMERIC "0" 139 | -- Retrieval info: PRIVATE: OVERFLOW_CHECKING NUMERIC "0" 140 | -- Retrieval info: PRIVATE: Optimize NUMERIC "0" 141 | -- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" 142 | -- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" 143 | -- Retrieval info: PRIVATE: UNDERFLOW_CHECKING NUMERIC "0" 144 | -- Retrieval info: PRIVATE: UsedW NUMERIC "0" 145 | -- Retrieval info: PRIVATE: Width NUMERIC "8" 146 | -- Retrieval info: PRIVATE: dc_aclr NUMERIC "0" 147 | -- Retrieval info: PRIVATE: diff_widths NUMERIC "0" 148 | -- Retrieval info: PRIVATE: msb_usedw NUMERIC "0" 149 | -- Retrieval info: PRIVATE: output_width NUMERIC "8" 150 | -- Retrieval info: PRIVATE: rsEmpty NUMERIC "1" 151 | -- Retrieval info: PRIVATE: rsFull NUMERIC "0" 152 | -- Retrieval info: PRIVATE: rsUsedW NUMERIC "0" 153 | -- Retrieval info: PRIVATE: sc_aclr NUMERIC "1" 154 | -- Retrieval info: PRIVATE: sc_sclr NUMERIC "0" 155 | -- Retrieval info: PRIVATE: wsEmpty NUMERIC "0" 156 | -- Retrieval info: PRIVATE: wsFull NUMERIC "1" 157 | -- Retrieval info: PRIVATE: wsUsedW NUMERIC "0" 158 | -- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all 159 | -- Retrieval info: CONSTANT: ADD_RAM_OUTPUT_REGISTER STRING "OFF" 160 | -- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" 161 | -- Retrieval info: CONSTANT: LPM_NUMWORDS NUMERIC "64" 162 | -- Retrieval info: CONSTANT: LPM_SHOWAHEAD STRING "OFF" 163 | -- Retrieval info: CONSTANT: LPM_TYPE STRING "scfifo" 164 | -- Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "8" 165 | -- Retrieval info: CONSTANT: LPM_WIDTHU NUMERIC "6" 166 | -- Retrieval info: CONSTANT: OVERFLOW_CHECKING STRING "ON" 167 | -- Retrieval info: CONSTANT: UNDERFLOW_CHECKING STRING "ON" 168 | -- Retrieval info: CONSTANT: USE_EAB STRING "ON" 169 | -- Retrieval info: USED_PORT: aclr 0 0 0 0 INPUT NODEFVAL "aclr" 170 | -- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL "clock" 171 | -- Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL "data[7..0]" 172 | -- Retrieval info: USED_PORT: empty 0 0 0 0 OUTPUT NODEFVAL "empty" 173 | -- Retrieval info: USED_PORT: full 0 0 0 0 OUTPUT NODEFVAL "full" 174 | -- Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]" 175 | -- Retrieval info: USED_PORT: rdreq 0 0 0 0 INPUT NODEFVAL "rdreq" 176 | -- Retrieval info: USED_PORT: wrreq 0 0 0 0 INPUT NODEFVAL "wrreq" 177 | -- Retrieval info: CONNECT: @aclr 0 0 0 0 aclr 0 0 0 0 178 | -- Retrieval info: CONNECT: @clock 0 0 0 0 clock 0 0 0 0 179 | -- Retrieval info: CONNECT: @data 0 0 8 0 data 0 0 8 0 180 | -- Retrieval info: CONNECT: @rdreq 0 0 0 0 rdreq 0 0 0 0 181 | -- Retrieval info: CONNECT: @wrreq 0 0 0 0 wrreq 0 0 0 0 182 | -- Retrieval info: CONNECT: empty 0 0 0 0 @empty 0 0 0 0 183 | -- Retrieval info: CONNECT: full 0 0 0 0 @full 0 0 0 0 184 | -- Retrieval info: CONNECT: q 0 0 8 0 @q 0 0 8 0 185 | -- Retrieval info: GEN_FILE: TYPE_NORMAL tap_fifo.vhd TRUE 186 | -- Retrieval info: GEN_FILE: TYPE_NORMAL tap_fifo.inc FALSE 187 | -- Retrieval info: GEN_FILE: TYPE_NORMAL tap_fifo.cmp FALSE 188 | -- Retrieval info: GEN_FILE: TYPE_NORMAL tap_fifo.bsf FALSE 189 | -- Retrieval info: GEN_FILE: TYPE_NORMAL tap_fifo_inst.vhd FALSE 190 | -- Retrieval info: LIB_FILE: altera_mf 191 | -------------------------------------------------------------------------------- /rtl/sid/wave_map.vhd: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | -- 3 | -- (C) COPYRIGHT 2010 Gideon's Logic Architectures' 4 | -- 5 | ------------------------------------------------------------------------------- 6 | -- 7 | -- Author: Gideon Zweijtzer (gideon.zweijtzer (at) gmail.com) 8 | -- 9 | -- Note that this file is copyrighted, and is not supposed to be used in other 10 | -- projects without written permission from the author. 11 | -- 12 | ------------------------------------------------------------------------------- 13 | library ieee; 14 | use ieee.std_logic_1164.all; 15 | use ieee.numeric_std.all; 16 | 17 | entity wave_map is 18 | generic ( 19 | g_num_voices : integer := 8; -- 8 or 16, clock should then be 8 or 16 MHz, too! 20 | g_sample_bits : integer := 8 ); 21 | port ( 22 | clock : in std_logic; 23 | reset : in std_logic; 24 | 25 | osc_val : in unsigned(23 downto 0); 26 | carry_20 : in std_logic; 27 | 28 | msb_other: in std_logic := '0'; 29 | ring_mod : in std_logic := '0'; 30 | test : in std_logic := '0'; 31 | 32 | voice_i : in unsigned(3 downto 0); 33 | comb_mode: in std_logic; 34 | enable_i : in std_logic; 35 | wave_sel : in std_logic_vector(3 downto 0); 36 | sq_width : in unsigned(11 downto 0); 37 | 38 | voice_o : out unsigned(3 downto 0); 39 | enable_o : out std_logic; 40 | wave_out : out unsigned(g_sample_bits-1 downto 0) ); 41 | 42 | end wave_map; 43 | 44 | 45 | architecture Gideon of wave_map is 46 | type noise_array_t is array (natural range <>) of unsigned(22 downto 0); 47 | signal noise_reg : noise_array_t(0 to g_num_voices-1) := (others => (0 => '1', others => '0')); 48 | type voice_array_t is array (natural range <>) of unsigned(g_sample_bits-1 downto 0); 49 | signal voice_reg : voice_array_t(0 to g_num_voices-1) := (others => (others => '0')); 50 | 51 | type t_byte_array is array(natural range <>) of unsigned(7 downto 0); 52 | constant c_wave_TP : t_byte_array(0 to 255) := ( 53 | 16#FF# => X"FF", 16#F7# => X"F7", 16#EF# => X"EF", 16#E7# => X"E0", 54 | 16#FE# => X"FE", 16#F6# => X"F0", 16#EE# => X"E0", 16#E6# => X"00", 55 | 16#FD# => X"FD", 16#F5# => X"FD", 16#ED# => X"E0", 16#E5# => X"00", 56 | 16#FC# => X"F8", 16#F4# => X"80", 16#EC# => X"00", 16#E4# => X"00", 57 | 16#FB# => X"FB", 16#F3# => X"F0", 16#EB# => X"E0", 16#E3# => X"00", 58 | 16#FA# => X"F8", 16#F2# => X"08", 16#EA# => X"00", 16#E2# => X"00", 59 | 16#F9# => X"F0", 16#F1# => X"00", 16#E9# => X"00", 16#E1# => X"00", 60 | 16#F8# => X"80", 16#F0# => X"00", 16#E8# => X"00", 16#E0# => X"00", 61 | 62 | 16#DF# => X"DF", 16#DE# => X"D0", 16#DD# => X"C0", 16#DB# => X"C0", 63 | 16#D7# => X"C0", 16#CF# => X"C0", 16#BF# => X"BF", 16#BE# => X"B0", 64 | 16#BD# => X"A0", 16#B9# => X"80", 16#B7# => X"80", 16#AF# => X"80", 65 | 66 | 16#7F# => X"7F", 16#7E# => X"70", 16#7D# => X"70", 16#7B# => X"60", 67 | 16#77# => X"40", others => X"00" ); 68 | 69 | constant c_wave_TS : t_byte_array(0 to 255) := ( 70 | 16#7F# => X"1E", 16#FE# => X"18", 16#FF# => X"3E", others => X"00" ); 71 | 72 | begin 73 | process(clock) 74 | variable noise_tmp : unsigned(22 downto 0); 75 | variable voice_tmp : unsigned(g_sample_bits-1 downto 0); 76 | variable triangle : unsigned(g_sample_bits-1 downto 0); 77 | variable square : unsigned(g_sample_bits-1 downto 0); 78 | variable sawtooth : unsigned(g_sample_bits-1 downto 0); 79 | variable out_tmp : unsigned(g_sample_bits-1 downto 0); 80 | variable new_bit : std_logic; 81 | begin 82 | if rising_edge(clock) then 83 | -- take top of list 84 | voice_tmp := voice_reg(0); 85 | noise_tmp := noise_reg(0); 86 | 87 | if reset='1' or test='1' then 88 | noise_tmp := (others => '1'); -- seed not equal to zero 89 | elsif carry_20='1' then 90 | new_bit := noise_tmp(22) xor noise_tmp(21) xor noise_tmp(20) xor noise_tmp(15); 91 | noise_tmp := noise_tmp(21 downto 0) & new_bit; 92 | end if; 93 | 94 | if osc_val(23)='1' then 95 | triangle := not osc_val(22 downto 23-g_sample_bits); 96 | else 97 | triangle := osc_val(22 downto 23-g_sample_bits); 98 | end if; 99 | if ring_mod='1' and msb_other='0' then 100 | triangle := not triangle; 101 | end if; 102 | 103 | sawtooth := osc_val(23 downto 24-g_sample_bits); 104 | if osc_val(23 downto 12) < sq_width then 105 | square := (others => '0'); 106 | else 107 | square := (others => '1'); 108 | end if; 109 | 110 | out_tmp := (others => '0'); 111 | case wave_sel is 112 | when X"0" => 113 | out_tmp := voice_tmp; 114 | when X"1" => 115 | out_tmp := triangle; 116 | when X"2" => 117 | out_tmp := sawtooth; 118 | when X"3" => 119 | if comb_mode='0' then 120 | out_tmp(g_sample_bits-1 downto g_sample_bits-8) := 121 | c_wave_TS(to_integer(osc_val(23 downto 23-g_sample_bits))); 122 | else -- 8580 123 | out_tmp := triangle and sawtooth; 124 | end if; 125 | when X"4" => 126 | out_tmp := square; 127 | when X"5" => -- combined triangle and square 128 | if comb_mode='0' then 129 | if square(0)='1' then 130 | out_tmp(g_sample_bits-1 downto g_sample_bits-8) := 131 | c_wave_TP(to_integer(triangle(g_sample_bits-1 downto g_sample_bits-8))); 132 | end if; 133 | else -- 8580 134 | out_tmp := triangle and square; 135 | end if; 136 | when X"6" => -- combined saw and pulse 137 | if comb_mode='1' then 138 | out_tmp := sawtooth and square; 139 | end if; 140 | 141 | when X"7" => -- combined triangle, saw and pulse 142 | if comb_mode='1' then 143 | out_tmp := triangle and sawtooth and square; 144 | end if; 145 | 146 | when X"8" => 147 | out_tmp(g_sample_bits-1) := noise_tmp(22); -- unsure.. 21? 148 | out_tmp(g_sample_bits-2) := noise_tmp(20); 149 | out_tmp(g_sample_bits-3) := noise_tmp(16); 150 | out_tmp(g_sample_bits-4) := noise_tmp(13); 151 | out_tmp(g_sample_bits-5) := noise_tmp(11); 152 | out_tmp(g_sample_bits-6) := noise_tmp(7); 153 | out_tmp(g_sample_bits-7) := noise_tmp(4); 154 | out_tmp(g_sample_bits-8) := noise_tmp(2); 155 | 156 | -- when X"9"|X"A"|X"B"|X"C"|X"D"|X"E"|X"F" => 157 | -- out_tmp := noise_tmp(20 downto 21-g_sample_bits); 158 | -- noise_tmp := (others => '0'); 159 | when others => 160 | null; 161 | end case; 162 | 163 | if enable_i='1' then 164 | noise_reg(g_num_voices-1) <= noise_tmp; 165 | noise_reg(0 to g_num_voices-2) <= noise_reg(1 to g_num_voices-1); 166 | voice_reg(g_num_voices-1) <= out_tmp; 167 | voice_reg(0 to g_num_voices-2) <= voice_reg(1 to g_num_voices-1); 168 | end if; 169 | 170 | --out_tmp(out_tmp'high) := not out_tmp(out_tmp'high); 171 | wave_out <= unsigned(out_tmp); 172 | 173 | voice_o <= voice_i; 174 | enable_o <= enable_i; 175 | end if; 176 | end process; 177 | 178 | end Gideon; 179 | -------------------------------------------------------------------------------- /rtl/sid/adsr_multi.vhd: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | -- 3 | -- (C) COPYRIGHT 2010 Gideon's Logic Architectures' 4 | -- 5 | ------------------------------------------------------------------------------- 6 | -- 7 | -- Author: Gideon Zweijtzer (gideon.zweijtzer (at) gmail.com) 8 | -- 9 | -- Note that this file is copyrighted, and is not supposed to be used in other 10 | -- projects without written permission from the author. 11 | -- 12 | ------------------------------------------------------------------------------- 13 | library ieee; 14 | use ieee.std_logic_1164.all; 15 | use ieee.numeric_std.all; 16 | use work.sid_debug_pkg.all; 17 | 18 | -- LUT: 195, FF:68 19 | 20 | entity adsr_multi is 21 | generic ( 22 | g_num_voices : integer := 8 ); 23 | port ( 24 | clock : in std_logic; 25 | reset : in std_logic; 26 | 27 | voice_i : in unsigned(3 downto 0); 28 | enable_i : in std_logic; 29 | voice_o : out unsigned(3 downto 0); 30 | enable_o : out std_logic; 31 | 32 | gate : in std_logic; 33 | attack : in std_logic_vector(3 downto 0); 34 | decay : in std_logic_vector(3 downto 0); 35 | sustain : in std_logic_vector(3 downto 0); 36 | release : in std_logic_vector(3 downto 0); 37 | 38 | env_state: out std_logic_vector(1 downto 0); -- for testing only 39 | env_out : out unsigned(7 downto 0) ); 40 | 41 | end adsr_multi; 42 | 43 | -- 158 1 62 .. FF 44 | -- 45 2 35 .. 61 45 | -- 26 4 1C .. 34 46 | -- 13 8 0D .. 1B 47 | -- 6 16 07 .. 0C 48 | -- 7 30 00 .. 06 49 | 50 | architecture gideon of adsr_multi is 51 | 52 | type presc_array_t is array(natural range <>) of unsigned(15 downto 0); 53 | constant prescalers : presc_array_t(0 to 15) := ( 54 | X"0008", X"001F", X"003E", X"005E", 55 | X"0094", X"00DB", X"010A", X"0138", 56 | X"0187", X"03D0", X"07A1", X"0C35", 57 | X"0F42", X"2DC7", X"4C4B", X"7A12" ); 58 | 59 | 60 | signal enveloppe : unsigned(7 downto 0) := (others => '0'); 61 | signal state : unsigned(1 downto 0) := (others => '0'); 62 | 63 | constant st_release : unsigned(1 downto 0) := "00"; 64 | constant st_attack : unsigned(1 downto 0) := "01"; 65 | constant st_decay : unsigned(1 downto 0) := "11"; 66 | 67 | type state_array_t is array(natural range <>) of unsigned(29 downto 0); 68 | signal state_array : state_array_t(0 to g_num_voices-1) := (others => (others => '0')); 69 | begin 70 | env_out <= enveloppe; 71 | env_state <= std_logic_vector(state); 72 | 73 | -- FF-5E 01 74 | -- 5D-37 02 75 | -- 36-1B 04 76 | -- 1A-0F 08 77 | -- 0E-07 10 78 | -- 06-01 1E 79 | process(clock) 80 | function logarithmic(lev: unsigned(7 downto 0)) return unsigned is 81 | variable res : unsigned(4 downto 0); 82 | begin 83 | if lev = X"00" then 84 | res := "00000"; -- prescaler off 85 | elsif lev < X"07" then 86 | res := "11101"; -- 1E-1 87 | elsif lev < X"0F" then 88 | res := "01111"; -- 10-1 89 | elsif lev < X"1B" then 90 | res := "00111"; -- 08-1 91 | elsif lev < X"37" then 92 | res := "00011"; -- 04-1 93 | elsif lev < X"5E" then 94 | res := "00001"; -- 02-1 95 | else 96 | res := "00000"; -- 01-1 97 | end if; 98 | return res; 99 | end function logarithmic; 100 | 101 | variable presc_select : integer range 0 to 15; 102 | variable cur_state : unsigned(1 downto 0); 103 | variable cur_env : unsigned(7 downto 0); 104 | variable cur_pre15 : unsigned(14 downto 0); 105 | variable cur_pre5 : unsigned(4 downto 0); 106 | variable next_state : unsigned(1 downto 0); 107 | variable next_env : unsigned(7 downto 0); 108 | variable next_pre15 : unsigned(14 downto 0); 109 | variable next_pre5 : unsigned(4 downto 0); 110 | variable presc_val : unsigned(14 downto 0); 111 | variable log_div : unsigned(4 downto 0); 112 | variable do_count_15 : std_logic; 113 | variable do_count_5 : std_logic; 114 | begin 115 | if rising_edge(clock) then 116 | cur_state := state_array(0)(1 downto 0); 117 | cur_env := state_array(0)(9 downto 2); 118 | cur_pre15 := state_array(0)(24 downto 10); 119 | cur_pre5 := state_array(0)(29 downto 25); 120 | 121 | voice_o <= voice_i; 122 | enable_o <= enable_i; 123 | 124 | next_state := cur_state; 125 | next_env := cur_env; 126 | next_pre15 := cur_pre15; 127 | next_pre5 := cur_pre5; 128 | 129 | 130 | -- PRESCALER LOGIC, output: do_count -- 131 | -- 15 bit prescaler select -- 132 | case cur_state is 133 | when st_attack => 134 | presc_select := to_integer(unsigned(attack)); 135 | when st_decay => 136 | presc_select := to_integer(unsigned(decay)); 137 | when others => -- includes release and idle 138 | presc_select := to_integer(unsigned(release)); 139 | end case; 140 | presc_val := prescalers(presc_select)(14 downto 0); 141 | 142 | -- 15 bit prescaler counter -- 143 | do_count_15 := '0'; 144 | if cur_pre15 = presc_val then 145 | next_pre15 := (others => '0'); 146 | do_count_15 := '1'; 147 | else 148 | next_pre15 := cur_pre15 + 1; 149 | end if; 150 | 151 | -- 5 bit prescaler -- 152 | log_div := logarithmic(cur_env); 153 | do_count_5 := '0'; 154 | if do_count_15='1' then 155 | if (cur_state = st_attack) or cur_pre5 = log_div then 156 | next_pre5 := "00000"; 157 | do_count_5 := '1'; 158 | else 159 | next_pre5 := cur_pre5 + 1; 160 | end if; 161 | end if; 162 | -- END PRESCALER LOGIC -- 163 | 164 | case cur_state is 165 | 166 | when st_attack => 167 | if gate = '0' then 168 | next_state := st_release; 169 | elsif cur_env = X"FF" then 170 | next_state := st_decay; 171 | end if; 172 | 173 | if do_count_15='1' then 174 | next_env := cur_env + 1; 175 | -- if cur_env = X"FE" or cur_env = X"FF" then -- result could be FF, but also 00!! 176 | -- next_state := st_decay; 177 | -- end if; 178 | end if; 179 | 180 | when st_decay => 181 | if gate = '0' then 182 | next_state := st_release; 183 | end if; 184 | 185 | if do_count_15='1' and do_count_5='1' and 186 | std_logic_vector(cur_env) /= (sustain & sustain) and 187 | cur_env /= X"00" then 188 | next_env := cur_env - 1; 189 | end if; 190 | 191 | when st_release => 192 | if gate = '1' then 193 | next_state := st_attack; 194 | end if; 195 | 196 | if do_count_15='1' and do_count_5='1' and 197 | cur_env /= X"00" then 198 | next_env := cur_env - 1; 199 | end if; 200 | 201 | when others => 202 | next_state := st_release; 203 | 204 | end case; 205 | 206 | if enable_i='1' then 207 | state_array(0 to g_num_voices-2) <= state_array(1 to g_num_voices-1); 208 | state_array(g_num_voices-1) <= next_pre5 & next_pre15 & next_env & next_state; 209 | enveloppe <= next_env; 210 | state <= next_state; 211 | end if; 212 | 213 | if reset='1' then 214 | state <= "00"; 215 | enveloppe <= (others => '0'); 216 | enable_o <= '0'; 217 | end if; 218 | end if; 219 | end process; 220 | end gideon; 221 | -------------------------------------------------------------------------------- /rtl/sid/mult_acc.vhd: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | -- 3 | -- (C) COPYRIGHT 2010 Gideon's Logic Architectures' 4 | -- 5 | ------------------------------------------------------------------------------- 6 | -- 7 | -- Author: Gideon Zweijtzer (gideon.zweijtzer (at) gmail.com) 8 | -- 9 | -- Note that this file is copyrighted, and is not supposed to be used in other 10 | -- projects without written permission from the author. 11 | -- 12 | ------------------------------------------------------------------------------- 13 | library ieee; 14 | use ieee.std_logic_1164.all; 15 | use ieee.numeric_std.all; 16 | 17 | library work; 18 | use work.my_math_pkg.all; 19 | 20 | entity mult_acc is 21 | port ( 22 | clock : in std_logic; 23 | reset : in std_logic; 24 | 25 | voice_i : in unsigned(3 downto 0); 26 | enable_i : in std_logic; 27 | voice3_off_l : in std_logic; 28 | voice3_off_r : in std_logic; 29 | 30 | filter_en : in std_logic := '0'; 31 | 32 | enveloppe : in unsigned(7 downto 0); 33 | waveform : in unsigned(11 downto 0); 34 | 35 | -- 36 | osc3 : out std_logic_vector(7 downto 0); 37 | env3 : out std_logic_vector(7 downto 0); 38 | 39 | -- 40 | valid_out : out std_logic; 41 | 42 | direct_out_L : out signed(17 downto 0); 43 | direct_out_R : out signed(17 downto 0); 44 | 45 | filter_out_L : out signed(17 downto 0); 46 | filter_out_R : out signed(17 downto 0) ); 47 | end mult_acc; 48 | 49 | -- architecture unsigned_wave of mult_acc is 50 | -- signal filter_m : std_logic; 51 | -- signal voice_m : unsigned(3 downto 0); 52 | -- signal mult_m : unsigned(19 downto 0); 53 | -- signal accu_f : unsigned(17 downto 0); 54 | -- signal accu_u : unsigned(17 downto 0); 55 | -- signal enable_d : std_logic; 56 | -- signal direct_i : unsigned(17 downto 0); 57 | -- signal filter_i : unsigned(17 downto 0); 58 | -- begin 59 | -- process(clock) 60 | -- variable mult_ext : unsigned(21 downto 0); 61 | -- variable mult_trunc : unsigned(21 downto 4); 62 | -- begin 63 | -- if rising_edge(clock) then 64 | -- -- latch outputs 65 | -- if reset='1' then 66 | -- osc3 <= (others => '0'); 67 | -- env3 <= (others => '0'); 68 | -- elsif voice_i = X"2" then 69 | -- osc3 <= std_logic_vector(waveform(11 downto 4)); 70 | -- env3 <= std_logic_vector(enveloppe); 71 | -- end if; 72 | -- 73 | -- mult_ext := extend(mult_m, mult_ext'length); 74 | -- mult_trunc := mult_ext(mult_trunc'range); 75 | -- filter_m <= filter_en; 76 | -- voice_m <= voice_i; 77 | -- mult_m <= enveloppe * waveform; 78 | -- valid_out <= '0'; 79 | -- enable_d <= enable_i; 80 | -- 81 | -- if enable_d='1' then 82 | -- if voice_m = 0 then 83 | -- valid_out <= '1'; 84 | -- direct_i <= accu_u; 85 | -- filter_i <= accu_f; 86 | -- if filter_m='1' then 87 | -- accu_f <= mult_trunc; 88 | -- accu_u <= (others => '0'); 89 | -- else 90 | -- accu_f <= (others => '0'); 91 | -- accu_u <= mult_trunc; 92 | -- end if; 93 | -- else 94 | -- valid_out <= '0'; 95 | -- if filter_m='1' then 96 | -- accu_f <= sum_limit(accu_f, mult_trunc); 97 | -- else 98 | -- if (voice_m /= 2) or (voice3_off = '0') then 99 | -- accu_u <= sum_limit(accu_u, mult_trunc); 100 | -- end if; 101 | -- end if; 102 | -- end if; 103 | -- end if; 104 | -- 105 | -- if reset = '1' then 106 | -- valid_out <= '0'; 107 | -- accu_u <= (others => '0'); 108 | -- accu_f <= (others => '0'); 109 | -- direct_i <= (others => '0'); 110 | -- filter_i <= (others => '0'); 111 | -- end if; 112 | -- end if; 113 | -- end process; 114 | -- 115 | -- direct_out <= '0' & signed(direct_i(17 downto 1)); 116 | -- filter_out <= '0' & signed(filter_i(17 downto 1)); 117 | -- end unsigned_wave; 118 | -- 119 | 120 | architecture signed_wave of mult_acc is 121 | signal filter_m : std_logic; 122 | signal voice_m : unsigned(3 downto 0); 123 | signal mult_m : signed(20 downto 0); 124 | signal accu_fl : signed(17 downto 0); 125 | signal accu_fr : signed(17 downto 0); 126 | signal accu_ul : signed(17 downto 0); 127 | signal accu_ur : signed(17 downto 0); 128 | signal enable_d : std_logic; 129 | begin 130 | process(clock) 131 | variable mult_ext : signed(21 downto 0); 132 | variable mult_trunc : signed(21 downto 4); 133 | variable env_signed : signed(8 downto 0); 134 | variable wave_signed: signed(11 downto 0); 135 | begin 136 | if rising_edge(clock) then 137 | -- latch outputs 138 | if reset='1' then 139 | osc3 <= (others => '0'); 140 | env3 <= (others => '0'); 141 | elsif voice_i = X"2" then 142 | osc3 <= std_logic_vector(waveform(11 downto 4)); 143 | env3 <= std_logic_vector(enveloppe); 144 | end if; 145 | 146 | env_signed := '0' & signed(enveloppe); 147 | wave_signed := not waveform(11) & signed(waveform(10 downto 0)); 148 | 149 | mult_ext := extend(mult_m, mult_ext'length); 150 | mult_trunc := mult_ext(mult_trunc'range); 151 | filter_m <= filter_en; 152 | voice_m <= voice_i; 153 | mult_m <= env_signed * wave_signed; 154 | valid_out <= '0'; 155 | enable_d <= enable_i; 156 | if enable_d='1' then 157 | if voice_m = 0 then 158 | valid_out <= '1'; 159 | direct_out_l <= accu_ul; 160 | direct_out_r <= accu_ur; 161 | filter_out_l <= accu_fl; 162 | filter_out_r <= accu_fr; 163 | accu_fr <= (others => '0'); 164 | accu_ur <= (others => '0'); 165 | if filter_m='1' then 166 | accu_fl <= mult_trunc; 167 | accu_ul <= (others => '0'); 168 | else 169 | accu_fl <= (others => '0'); 170 | accu_ul <= mult_trunc; 171 | end if; 172 | elsif voice_m(3)='0' then 173 | valid_out <= '0'; 174 | if filter_m='1' then 175 | accu_fl <= sum_limit(accu_fl, mult_trunc); 176 | else 177 | if (voice_m /= 2) or (voice3_off_l = '0') then 178 | accu_ul <= sum_limit(accu_ul, mult_trunc); 179 | end if; 180 | end if; 181 | else -- upper 8 voices go to right 182 | valid_out <= '0'; 183 | if filter_m='1' then 184 | accu_fr <= sum_limit(accu_fr, mult_trunc); 185 | else 186 | if (voice_m /= 10) or (voice3_off_r = '0') then 187 | accu_ur <= sum_limit(accu_ur, mult_trunc); 188 | end if; 189 | end if; 190 | end if; 191 | 192 | end if; 193 | 194 | if reset = '1' then 195 | valid_out <= '0'; 196 | accu_ul <= (others => '0'); 197 | accu_fl <= (others => '0'); 198 | accu_ur <= (others => '0'); 199 | accu_fr <= (others => '0'); 200 | direct_out_l <= (others => '0'); 201 | direct_out_r <= (others => '0'); 202 | filter_out_l <= (others => '0'); 203 | filter_out_r <= (others => '0'); 204 | end if; 205 | end if; 206 | end process; 207 | 208 | 209 | end signed_wave; 210 | -------------------------------------------------------------------------------- /rtl/sid8580/sid8580.v: -------------------------------------------------------------------------------- 1 | module sid8580 (clk_1MHz, clk32, reset, cs, we, addr, data_in, data_out, 2 | pot_x, pot_y, audio_data, extfilter_en); 3 | 4 | // Input Ports 5 | input wire [0:0] clk_1MHz; 6 | input wire [0:0] clk32; 7 | input wire [0:0] reset; 8 | input wire [0:0] cs; 9 | input wire [0:0] we; 10 | input wire [4:0] addr; 11 | input wire [7:0] data_in; 12 | input wire [7:0] pot_x; 13 | input wire [7:0] pot_y; 14 | input wire [0:0] extfilter_en; 15 | 16 | // Output Ports 17 | output wire [ 7:0] data_out; 18 | output wire [15:0] audio_data; 19 | 20 | // Internal Signals 21 | reg [7:0] Voice_1_Freq_lo; 22 | reg [7:0] Voice_1_Freq_hi; 23 | reg [7:0] Voice_1_Pw_lo; 24 | reg [3:0] Voice_1_Pw_hi; 25 | reg [7:0] Voice_1_Control; 26 | reg [7:0] Voice_1_Att_dec; 27 | reg [7:0] Voice_1_Sus_Rel; 28 | 29 | reg [7:0] Voice_2_Freq_lo; 30 | reg [7:0] Voice_2_Freq_hi; 31 | reg [7:0] Voice_2_Pw_lo; 32 | reg [3:0] Voice_2_Pw_hi; 33 | reg [7:0] Voice_2_Control; 34 | reg [7:0] Voice_2_Att_dec; 35 | reg [7:0] Voice_2_Sus_Rel; 36 | 37 | reg [7:0] Voice_3_Freq_lo; 38 | reg [7:0] Voice_3_Freq_hi; 39 | reg [7:0] Voice_3_Pw_lo; 40 | reg [3:0] Voice_3_Pw_hi; 41 | reg [7:0] Voice_3_Control; 42 | reg [7:0] Voice_3_Att_dec; 43 | reg [7:0] Voice_3_Sus_Rel; 44 | 45 | reg [7:0] Filter_Fc_lo; 46 | reg [7:0] Filter_Fc_hi; 47 | reg [7:0] Filter_Res_Filt; 48 | reg [7:0] Filter_Mode_Vol; 49 | 50 | wire [7:0] Misc_Osc3_Random; 51 | wire [7:0] Misc_Env3; 52 | 53 | reg [7:0] Ext_hi; 54 | reg [3:0] Ext_lo; 55 | 56 | reg [7:0] do_buf; 57 | reg [7:0] sidrandom; 58 | 59 | wire [11:0] voice_1; 60 | wire [11:0] voice_2; 61 | wire [11:0] voice_3; 62 | wire [17:0] voice_mixed; 63 | reg [17:0] voice_volume; 64 | 65 | wire [ 0:0] voice_1_PA_MSB; 66 | wire [ 0:0] voice_2_PA_MSB; 67 | wire [ 0:0] voice_3_PA_MSB; 68 | 69 | wire [18:0] filtered_audio; 70 | reg [ 0:0] tick_q1; 71 | reg [ 0:0] tick_q2; 72 | reg [ 0:0] input_valid; 73 | wire [17:0] unsigned_audio; 74 | wire [18:0] unsigned_filt; 75 | reg [ 0:0] ff1; 76 | 77 | localparam DC_offset = 14'b00111111111111; 78 | 79 | // Voice 1 Instantiation 80 | sid_voice v1 (.clock(clk_1MHz), .reset(reset), 81 | .freq_lo(Voice_1_Freq_lo), .freq_hi(Voice_1_Freq_hi), 82 | .pw_lo(Voice_1_Pw_lo), .pw_hi(Voice_1_Pw_hi), 83 | .control(Voice_1_Control), 84 | .att_dec(Voice_1_Att_dec), .sus_rel(Voice_1_Sus_Rel), 85 | .osc_msb_in(voice_3_PA_MSB), .osc_msb_out(voice_1_PA_MSB), 86 | .signal_out(voice_1)); 87 | 88 | // Voice 2 Instantiation 89 | sid_voice v2 (.clock(clk_1MHz), .reset(reset), 90 | .freq_lo(Voice_2_Freq_lo), .freq_hi(Voice_2_Freq_hi), 91 | .pw_lo(Voice_2_Pw_lo), .pw_hi(Voice_2_Pw_hi), 92 | .control(Voice_2_Control), 93 | .att_dec(Voice_2_Att_dec), .sus_rel(Voice_2_Sus_Rel), 94 | .osc_msb_in(voice_1_PA_MSB), .osc_msb_out(voice_2_PA_MSB), 95 | .signal_out(voice_2)); 96 | 97 | // Voice 3 Instantiation 98 | sid_voice v3 (.clock(clk_1MHz), .reset(reset), 99 | .freq_lo(Voice_3_Freq_lo), .freq_hi(Voice_3_Freq_hi), 100 | .pw_lo(Voice_3_Pw_lo), .pw_hi(Voice_3_Pw_hi), 101 | .control(Voice_3_Control), 102 | .att_dec(Voice_3_Att_dec), .sus_rel(Voice_3_Sus_Rel), 103 | .osc_msb_in(voice_2_PA_MSB), .osc_msb_out(voice_3_PA_MSB), 104 | .signal_out(voice_3), .osc_out(Misc_Osc3_Random), 105 | .env_out(Misc_Env3)); 106 | 107 | // Filter Instantiation 108 | sid_filters filters (.clk(clk32), .rst(reset), 109 | .Fc_lo(Filter_Fc_lo), .Fc_hi(Filter_Fc_hi), 110 | .Res_Filt(Filter_Res_Filt), .Mode_Vol(Filter_Mode_Vol), 111 | .voice1(voice_1), .voice2(voice_2), 112 | .voice3(voice_3), .input_valid(input_valid), 113 | .ext_in(12'hfff), .sound(audio_data), 114 | .extfilter_en(extfilter_en)); 115 | 116 | assign data_out = do_buf; 117 | //assign audio_data = {1'b0, (filtered_audio[18:5] + 14'b1000000000000000)}; 118 | //assign unsigned_filt = filtered_audio + 19'b1000000000000000000; 119 | //assign unsigned_audio = unsigned_filt[18:1]; 120 | //assign audio_data = filtered_audio[18:3];// + 15'h4000;//{1'b0, unsigned_audio[17:1]}; 121 | 122 | // Toggle Flip Flop 123 | always @(posedge clk_1MHz) 124 | begin 125 | if (reset) 126 | ff1 <= 1'b0; 127 | else 128 | ff1 <= ~ff1; 129 | end 130 | 131 | always @(posedge clk32) 132 | begin 133 | input_valid <= (tick_q1 != tick_q2) ? 1'b1 : 1'b0; 134 | tick_q1 <= ff1; 135 | tick_q2 <= tick_q1; 136 | end 137 | 138 | reg [7:0] last_wr; 139 | 140 | // Register Decoding 141 | always @(posedge clk32) 142 | begin 143 | if (reset) 144 | begin 145 | Voice_1_Freq_lo <= 8'h00; 146 | Voice_1_Freq_hi <= 8'h00; 147 | Voice_1_Pw_lo <= 8'h00; 148 | Voice_1_Pw_hi <= 4'h0; 149 | Voice_1_Control <= 8'h00; 150 | Voice_1_Att_dec <= 8'h00; 151 | Voice_1_Sus_Rel <= 8'h00; 152 | Voice_2_Freq_lo <= 8'h00; 153 | Voice_2_Freq_hi <= 8'h00; 154 | Voice_2_Pw_lo <= 8'h00; 155 | Voice_2_Pw_hi <= 4'h0; 156 | Voice_2_Control <= 8'h00; 157 | Voice_2_Att_dec <= 8'h00; 158 | Voice_2_Sus_Rel <= 8'h00; 159 | Voice_3_Freq_lo <= 8'h00; 160 | Voice_3_Freq_hi <= 8'h00; 161 | Voice_3_Pw_lo <= 8'h00; 162 | Voice_3_Pw_hi <= 4'h0; 163 | Voice_3_Control <= 8'h00; 164 | Voice_3_Att_dec <= 8'h00; 165 | Voice_3_Sus_Rel <= 8'h00; 166 | Filter_Fc_lo <= 8'h00; 167 | Filter_Fc_hi <= 8'h00; 168 | Filter_Res_Filt <= 8'h00; 169 | Filter_Mode_Vol <= 8'h00; 170 | Ext_hi <= 8'h00; 171 | Ext_lo <= 4'h0; 172 | end 173 | else 174 | begin 175 | Voice_1_Freq_lo <= Voice_1_Freq_lo; 176 | Voice_1_Freq_hi <= Voice_1_Freq_hi; 177 | Voice_1_Pw_lo <= Voice_1_Pw_lo; 178 | Voice_1_Pw_hi <= Voice_1_Pw_hi; 179 | Voice_1_Control <= Voice_1_Control; 180 | Voice_1_Att_dec <= Voice_1_Att_dec; 181 | Voice_1_Sus_Rel <= Voice_1_Sus_Rel; 182 | Voice_2_Freq_lo <= Voice_2_Freq_lo; 183 | Voice_2_Freq_hi <= Voice_2_Freq_hi; 184 | Voice_2_Pw_lo <= Voice_2_Pw_lo; 185 | Voice_2_Pw_hi <= Voice_2_Pw_hi; 186 | Voice_2_Control <= Voice_2_Control; 187 | Voice_2_Att_dec <= Voice_2_Att_dec; 188 | Voice_2_Sus_Rel <= Voice_2_Sus_Rel; 189 | Voice_3_Freq_lo <= Voice_3_Freq_lo; 190 | Voice_3_Freq_hi <= Voice_3_Freq_hi; 191 | Voice_3_Pw_lo <= Voice_3_Pw_lo; 192 | Voice_3_Pw_hi <= Voice_3_Pw_hi; 193 | Voice_3_Control <= Voice_3_Control; 194 | Voice_3_Att_dec <= Voice_3_Att_dec; 195 | Voice_3_Sus_Rel <= Voice_3_Sus_Rel; 196 | Filter_Fc_lo <= Filter_Fc_lo; 197 | Filter_Fc_hi <= Filter_Fc_hi; 198 | Filter_Res_Filt <= Filter_Res_Filt; 199 | Filter_Mode_Vol <= Filter_Mode_Vol; 200 | Ext_hi <= Ext_hi; 201 | Ext_lo <= Ext_lo; 202 | do_buf <= 8'h00; 203 | end 204 | if (cs) 205 | begin 206 | if (we) 207 | begin 208 | last_wr <= data_in; 209 | case (addr) 210 | 5'h00: Voice_1_Freq_lo <= data_in; 211 | 5'h01: Voice_1_Freq_hi <= data_in; 212 | 5'h02: Voice_1_Pw_lo <= data_in; 213 | 5'h03: Voice_1_Pw_hi <= data_in[3:0]; 214 | 5'h04: Voice_1_Control <= data_in; 215 | 5'h05: Voice_1_Att_dec <= data_in; 216 | 5'h06: Voice_1_Sus_Rel <= data_in; 217 | 5'h07: Voice_2_Freq_lo <= data_in; 218 | 5'h08: Voice_2_Freq_hi <= data_in; 219 | 5'h09: Voice_2_Pw_lo <= data_in; 220 | 5'h0a: Voice_2_Pw_hi <= data_in[3:0]; 221 | 5'h0b: Voice_2_Control <= data_in; 222 | 5'h0c: Voice_2_Att_dec <= data_in; 223 | 5'h0d: Voice_2_Sus_Rel <= data_in; 224 | 5'h0e: Voice_3_Freq_lo <= data_in; 225 | 5'h0f: Voice_3_Freq_hi <= data_in; 226 | 5'h10: Voice_3_Pw_lo <= data_in; 227 | 5'h11: Voice_3_Pw_hi <= data_in[3:0]; 228 | 5'h12: Voice_3_Control <= data_in; 229 | 5'h13: Voice_3_Att_dec <= data_in; 230 | 5'h14: Voice_3_Sus_Rel <= data_in; 231 | 5'h15: Filter_Fc_lo <= data_in; 232 | 5'h16: Filter_Fc_hi <= data_in; 233 | 5'h17: Filter_Res_Filt <= data_in; 234 | 5'h18: Filter_Mode_Vol <= data_in; 235 | 5'h19: Ext_lo <= data_in[3:0]; 236 | 5'h1a: Ext_hi <= data_in; 237 | default:; 238 | endcase 239 | end 240 | else 241 | begin 242 | case (addr) 243 | 5'h19: do_buf <= pot_x; 244 | 5'h1a: do_buf <= pot_y; 245 | 5'h1b: do_buf <= Misc_Osc3_Random; 246 | 5'h1c: do_buf <= Misc_Env3; 247 | default: do_buf <= last_wr; 248 | endcase 249 | end 250 | end 251 | end 252 | 253 | endmodule 254 | -------------------------------------------------------------------------------- /rtl/c1541/mist_sd_card.sv: -------------------------------------------------------------------------------- 1 | // 2 | // sd_card.v 3 | // 4 | // Copyright (c) 2016 Sorgelig 5 | // G64 parsing (c) 2022 Slingshot 6 | // 7 | // This source file is free software: you can redistribute it and/or modify 8 | // it under the terms of the Lesser GNU General Public License as published 9 | // by the Free Software Foundation, either version 3 of the License, or 10 | // (at your option) any later version. 11 | // 12 | // This source file is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public License 18 | // along with this program. If not, see . 19 | // 20 | // 21 | ///////////////////////////////////////////////////////////////////////// 22 | 23 | module mist_sd_card 24 | ( 25 | input clk, 26 | input reset, 27 | 28 | output [31:0] sd_lba, 29 | output reg sd_rd, 30 | output reg sd_wr, 31 | input sd_ack, 32 | 33 | input [8:0] sd_buff_addr, 34 | input [7:0] sd_buff_dout, 35 | output [7:0] sd_buff_din, 36 | input sd_buff_wr, 37 | 38 | input save_track, 39 | input change, 40 | input mount, 41 | input g64, 42 | input [6:0] track, 43 | 44 | input [12:0] ram_addr, 45 | input [7:0] ram_di, 46 | output [7:0] ram_do, 47 | input ram_we, 48 | 49 | output reg [7:0] id1, 50 | output reg [7:0] id2, 51 | output reg [1:0] freq, 52 | output reg [15:0] raw_track_len, 53 | output reg [6:0] max_track, 54 | output reg raw, 55 | output reg busy 56 | ); 57 | 58 | assign sd_lba = lba; 59 | 60 | wire [9:0] start_sectors[42] = 61 | '{ 0, 0, 21, 42, 63, 84,105,126,147,168,189,210,231,252,273,294,315,336,357,376,395, 62 | 414,433,452,471,490,508,526,544,562,580,598,615,632,649,666,683,700,717,734,751,768}; 63 | 64 | reg [23:0] g64_offsets[88]; 65 | reg [23:0] g64_offsets_din; 66 | wire [6:0] g64_offs_idx = sd_buff_addr[8:2] - 1'd1; 67 | reg [6:0] g64_track_idx; 68 | reg [23:0] g64_offsets_dout; 69 | always @(negedge clk) g64_offsets_dout <= g64_offsets[g64_track_idx]; 70 | reg g64_rd, g64_wr; 71 | reg [7:0] g64_tlen_lo; 72 | 73 | reg [1:0] freq_table[88]; 74 | 75 | reg [31:0] lba; 76 | reg [4:0] rel_lba; 77 | reg [4:0] track_lbas; 78 | 79 | reg new_disk; 80 | wire [6:0] new_track = new_disk ? raw ? 7'b1111111 : {6'h12, 1'b0} : track; 81 | 82 | reg [8:0] sector_offset; 83 | 84 | always @(posedge clk) begin 85 | reg old_ack; 86 | reg old_change; 87 | reg [6:0] cur_track = 0; 88 | reg ready = 0; 89 | reg saving = 0; 90 | 91 | old_ack <= sd_ack; 92 | if(sd_ack) {sd_rd,sd_wr} <= 0; 93 | 94 | old_change <= change; 95 | if(~old_change & change) begin 96 | ready <= mount; 97 | saving <= 0; 98 | busy <= 0; 99 | id1 <= 8'h20; 100 | id2 <= 8'h20; 101 | new_disk <= mount; 102 | raw <= g64; 103 | if(!g64) max_track <= 7'd80; 104 | {g64_rd, g64_wr} <= 0; 105 | end 106 | else 107 | if(reset) begin 108 | cur_track <= 'b1111111; 109 | busy <= 0; 110 | sd_rd <= 0; 111 | sd_wr <= 0; 112 | saving<= 0; 113 | id1 <= 8'h20; 114 | id2 <= 8'h20; 115 | new_disk <= 0; 116 | {g64_rd, g64_wr} <= 0; 117 | end 118 | else 119 | if(g64_rd) begin 120 | g64_rd <= 0; 121 | if (g64_offsets_dout != 0) begin 122 | sector_offset <= g64_offsets_dout[8:0]; 123 | lba <= g64_offsets_dout[23:9]; 124 | track_lbas <= 5'd1; // will read later 125 | sd_rd <= 1; 126 | busy <= 1; 127 | end 128 | else 129 | raw_track_len <= 0; 130 | end 131 | else 132 | if(g64_wr) begin 133 | g64_wr <= 0; 134 | if(g64_offsets_dout != 0) begin 135 | // sector offset and length is already determined in the read phase 136 | // rewind lba to the start of the track 137 | lba <= g64_offsets_dout[23:9]; 138 | saving <= 1; 139 | sd_wr <= 1; 140 | busy <= 1; 141 | end 142 | end 143 | else 144 | if(busy) begin 145 | // BAM offset A2 and A3 -> header ID1,ID2 146 | if(!raw && cur_track == {5'h12, 1'b0} && rel_lba == 0 && !saving && sd_buff_wr) begin 147 | if (sd_buff_addr == 9'h1a2) id1 <= sd_buff_dout; 148 | else if (sd_buff_addr == 9'h1a3) id2 <= sd_buff_dout; 149 | end 150 | 151 | // scan G64 track offsets 152 | if(raw && cur_track == 'b1111111 && !saving && sd_buff_wr) begin 153 | if ({rel_lba, sd_buff_addr} == 14'h9) max_track <= sd_buff_dout[6:0]; 154 | // track offsets 155 | if ({rel_lba, sd_buff_addr} >= 14'hc && {rel_lba, sd_buff_addr} <= 14'h15b) 156 | case (sd_buff_addr[1:0]) 157 | 2'b00: g64_offsets_din[ 7: 0] <= sd_buff_dout; 158 | 2'b01: g64_offsets_din[15: 8] <= sd_buff_dout; 159 | 2'b10: g64_offsets_din[23:16] <= sd_buff_dout; 160 | 2'b11: g64_offsets[g64_offs_idx] <= g64_offsets_din; 161 | default: ; 162 | endcase 163 | // speed zones 164 | if ({rel_lba, sd_buff_addr} >= 14'h15c && {rel_lba, sd_buff_addr} <= 14'h2ab && sd_buff_addr[1:0] == 0) 165 | freq_table[{rel_lba, sd_buff_addr[8:2]} - 8'h55] <= sd_buff_dout[1:0]; 166 | end 167 | // G64 track length 168 | if(raw && cur_track != 'b1111111 && !saving && sd_buff_wr) begin 169 | if ({rel_lba, sd_buff_addr} == sector_offset) g64_tlen_lo[7:0] <= sd_buff_dout; 170 | if ({rel_lba, sd_buff_addr} == sector_offset + 1'd1) begin 171 | raw_track_len <= {sd_buff_dout, g64_tlen_lo}; 172 | track_lbas <= (sector_offset + 2'd2 + {sd_buff_dout, g64_tlen_lo} + 9'd511) >> 4'd9; 173 | end 174 | end 175 | 176 | if(old_ack && ~sd_ack) begin 177 | if(track_lbas != 0 && rel_lba != track_lbas - 1'd1) begin 178 | lba <= lba + 1'd1; 179 | rel_lba <= rel_lba + 1'd1; 180 | if(saving) sd_wr <= 1; 181 | else sd_rd <= 1; 182 | end 183 | else 184 | if(saving && ((cur_track[6:1] != track[6:1]) || (raw && cur_track[0] != track[0]))) begin 185 | saving <= 0; 186 | cur_track <= track; 187 | rel_lba <= 0; 188 | if (raw) begin 189 | g64_track_idx <= track; 190 | g64_rd <= 1; 191 | end 192 | else begin 193 | sector_offset <= { start_sectors[track[6:1]][0], 8'd0 } ; 194 | lba <= start_sectors[track[6:1]][9:1]; 195 | track_lbas <= (start_sectors[track[6:1]+1'd1] - start_sectors[track[6:1]] + 1'd1) >> 1'd1; 196 | sd_rd <= 1; 197 | end 198 | end 199 | else 200 | begin 201 | freq <= freq_table[cur_track]; 202 | busy <= 0; 203 | end 204 | end 205 | end 206 | else 207 | if(ready) begin 208 | if(save_track && cur_track != 'b1111111) begin 209 | rel_lba <= 0; 210 | if (raw) begin 211 | g64_track_idx <= cur_track; 212 | g64_wr <= 1; 213 | end 214 | else begin 215 | saving <= 1; 216 | lba <= start_sectors[cur_track[6:1]][9:1]; 217 | sd_wr <= 1; 218 | busy <= 1; 219 | end 220 | end 221 | else 222 | if((cur_track[6:1] != track[6:1]) || (raw && cur_track[0] != track[0]) || new_disk) begin 223 | saving <= 0; 224 | new_disk <= 0; 225 | rel_lba <= 0; 226 | cur_track <= new_track; 227 | if (raw) begin 228 | // G64 support 229 | if (new_disk) begin 230 | lba <= 0; // read header 231 | track_lbas <= 5'd2; 232 | sd_rd <= 1; 233 | busy <= 1; 234 | end 235 | else begin 236 | g64_track_idx <= new_track; 237 | g64_rd <= 1; 238 | end 239 | end 240 | else begin 241 | sector_offset <= { start_sectors[new_track[6:1]][0], 8'd0 } ; 242 | lba <= start_sectors[new_track[6:1]][9:1]; 243 | track_lbas <= (start_sectors[new_track[6:1]+1'd1] - start_sectors[new_track[6:1]] + 1'd1) >> 1'd1; 244 | sd_rd <= 1; 245 | busy <= 1; 246 | end 247 | end 248 | end 249 | end 250 | 251 | // track buffer for maximum of 8192+512 bytes storage 252 | reg [7:0] track_buffer[8192]; 253 | reg [7:0] track_buffer_b[512]; 254 | 255 | // track buffer - IO controller side 256 | wire [13:0] sd_ram_addr = { rel_lba, sd_buff_addr }; 257 | reg [7:0] track_buffer_do_sd; 258 | reg [7:0] track_buffer_b_do_sd; 259 | assign sd_buff_din = sd_ram_addr[13] ? track_buffer_b_do_sd : track_buffer_do_sd; 260 | 261 | always @(posedge clk) begin 262 | 263 | if (sd_ack & sd_buff_wr & !sd_ram_addr[13]) track_buffer[sd_ram_addr[12:0]] <= sd_buff_dout; 264 | track_buffer_do_sd <= track_buffer[sd_ram_addr[12:0]]; 265 | 266 | if (sd_ack & sd_buff_wr & sd_ram_addr[13]) track_buffer_b[sd_ram_addr[8:0]] <= sd_buff_dout; 267 | track_buffer_b_do_sd <= track_buffer_b[sd_ram_addr[8:0]]; 268 | 269 | end 270 | 271 | // track buffer - GCR floppy side 272 | wire [13:0] fd_ram_addr = ram_addr + sector_offset; 273 | reg [7:0] track_buffer_do_fd; 274 | reg [7:0] track_buffer_b_do_fd; 275 | assign ram_do = fd_ram_addr[13] ? track_buffer_b_do_fd : track_buffer_do_fd; 276 | 277 | always @(posedge clk) begin 278 | 279 | if (ram_we & !fd_ram_addr[13]) track_buffer[fd_ram_addr[12:0]] <= ram_di; 280 | track_buffer_do_fd <= track_buffer[fd_ram_addr[12:0]]; 281 | 282 | if (ram_we & fd_ram_addr[13]) track_buffer_b[fd_ram_addr[8:0]] <= ram_di; 283 | track_buffer_b_do_fd <= track_buffer_b[fd_ram_addr[8:0]]; 284 | 285 | end 286 | 287 | endmodule 288 | -------------------------------------------------------------------------------- /rtl/c1530.vhd: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------- 2 | -- Commodore 1530 to SD card host (read only) by Dar (darfpga@aol.fr) 25-Mars-2019 3 | -- http://darfpga.blogspot.fr 4 | -- also darfpga on sourceforge 5 | -- 6 | -- tap/wav player 7 | -- Converted to 8 bit FIFO - Slingshot 8 | --------------------------------------------------------------------------------- 9 | 10 | library ieee; 11 | use ieee.std_logic_1164.all; 12 | use ieee.std_logic_unsigned.all; 13 | use ieee.numeric_std.all; 14 | 15 | entity c1530 is 16 | port( 17 | clk32 : in std_logic; 18 | restart_tape : in std_logic; -- keep to 1 to long enough to clear fifo 19 | -- reset tap header bytes skip counter 20 | 21 | wav_mode : in std_logic; -- 1 for wav mode, 0 for tap mode 22 | tap_version : in std_logic_vector(1 downto 0); -- tap file version (0-2) 23 | 24 | host_tap_in : in std_logic_vector(7 downto 0); -- 8bits fifo input 25 | host_tap_wrreq : in std_logic; -- set to 1 for 1 clk32 to write 1 word 26 | tap_fifo_wrfull : out std_logic; -- do not write when fifo tap_fifo_full = 1 27 | tap_fifo_error : out std_logic; -- fifo fall empty (unrecoverable error) 28 | 29 | osd_play_stop_toggle : in std_logic; -- PLAY/STOP toggle button from OSD 30 | osd_play_stop_reset : in std_logic; -- PLAY/STOP reset 31 | 32 | cass_sense : out std_logic; -- 0 = PLAY/REW/FF/REC button is pressed 33 | cass_read : buffer std_logic; -- tape read signal 34 | cass_write : in std_logic; -- signal to write on tape (not used) 35 | cass_motor : in std_logic; -- 0 = tape motor is powered 36 | cass_run : out std_logic; -- motor corrected with momentum 37 | 38 | ear_input : in std_logic -- tape input from EAR port 39 | ); 40 | end c1530; 41 | 42 | architecture struct of c1530 is 43 | 44 | signal tap_player_tick_cnt : std_logic_vector( 5 downto 0); 45 | signal wav_player_tick_cnt : std_logic_vector(11 downto 0); 46 | signal tap_dword : std_logic_vector(31 downto 0); 47 | signal wave_cnt : std_logic_vector(23 downto 0); 48 | signal wave_len : std_logic_vector(23 downto 0); 49 | 50 | signal tap_fifo_do : std_logic_vector(7 downto 0); 51 | signal tap_fifo_rdreq : std_logic; 52 | signal tap_fifo_empty : std_logic; 53 | signal get_24bits_len : std_logic; 54 | signal start_bytes : std_logic_vector(7 downto 0); 55 | signal skip_bytes : std_logic; 56 | signal playing : std_logic; -- 1 = tap or wav file is playing 57 | 58 | signal osd_play_stop_toggleD : std_logic; -- for detecting change in the OSD toggle button 59 | signal sense : std_logic; -- status of the PLAY/STOP tape button 60 | 61 | signal ear_inputD : std_logic; -- for detecting input from EAR port 62 | signal ear_input_detected : std_logic; -- 1=input from EAR port was detected 63 | signal ear_autostop_counter : std_logic_vector(28 downto 0); -- counter for stopping after a delay when ear is no longer detected 64 | 65 | signal cass_motor_D : std_logic; 66 | signal motor : std_logic; 67 | signal motor_counter : unsigned(23 downto 0); 68 | 69 | constant autostop_time: std_logic_vector(28 downto 0) := std_logic_vector(to_unsigned(32000000 * 5, ear_autostop_counter'length)); -- about 5 seconds 70 | 71 | 72 | begin 73 | 74 | -- for wav mode use large depth fifo (eg 512 x 32bits) 75 | -- for tap mode fifo may be smaller (eg 16 x 32bits) 76 | tap_fifo_inst : entity work.tap_fifo 77 | port map( 78 | aclr => restart_tape, 79 | data => host_tap_in, 80 | clock => clk32, 81 | rdreq => tap_fifo_rdreq, 82 | wrreq => host_tap_wrreq, 83 | q => tap_fifo_do, 84 | empty => tap_fifo_empty, 85 | full => tap_fifo_wrfull 86 | ); 87 | 88 | process(clk32, restart_tape) 89 | begin 90 | 91 | if restart_tape = '1' then 92 | 93 | start_bytes <= X"00"; 94 | skip_bytes <= '1'; 95 | tap_player_tick_cnt <= (others => '0'); 96 | wav_player_tick_cnt <= (others => '0'); 97 | wave_len <= (others => '0'); 98 | wave_cnt <= (others => '0'); 99 | get_24bits_len <= '0'; 100 | 101 | tap_fifo_rdreq <='0'; 102 | tap_fifo_error <='0'; -- run out of data 103 | 104 | sense <= '1'; -- STOP tape 105 | 106 | elsif rising_edge(clk32) then 107 | 108 | -- detect OSD PLAY/STOP button press 109 | osd_play_stop_toggleD <= osd_play_stop_toggle; 110 | if osd_play_stop_toggleD = '0' and osd_play_stop_toggle = '1' then 111 | sense <= not sense; 112 | end if; 113 | if osd_play_stop_reset = '1' then 114 | sense <= '1'; 115 | end if; 116 | 117 | -- detect EAR input 118 | ear_inputD <= ear_input; 119 | if ear_inputD /= ear_input then 120 | ear_input_detected <= '1'; 121 | ear_autostop_counter <= autostop_time; 122 | end if; 123 | 124 | -- EAR input 125 | if ear_input_detected='1' then 126 | sense <= '0'; -- automatically press PLAY 127 | cass_read <= not ear_input; 128 | 129 | -- autostop 130 | if ear_autostop_counter = 0 then 131 | ear_input_detected <= '0'; 132 | sense <= '1'; -- automatically press STOP 133 | else 134 | ear_autostop_counter <= ear_autostop_counter - "1"; 135 | end if; 136 | end if; 137 | 138 | -- simulate tape motor momentum 139 | cass_motor_D <= cass_motor; 140 | if cass_motor_D /= cass_motor then 141 | motor_counter <= to_unsigned(10*32000, motor_counter'length); 142 | elsif motor_counter /= 0 then 143 | motor_counter <= motor_counter - 1; 144 | else 145 | motor <= cass_motor; 146 | end if; 147 | 148 | playing <= (not motor) and (not sense) and (not ear_input_detected); -- cass_motor and sense are low active 149 | 150 | if playing = '0' and ear_input_detected = '0' then 151 | cass_read <= '1'; 152 | end if; 153 | 154 | tap_fifo_rdreq <= '0'; 155 | 156 | if (playing = '1') and (wav_mode = '1') then 157 | 158 | -- Wav player required a large depth fifo to give chance 159 | -- fifo not falling empty while host go reading next sd card sector 160 | -- (fifo is read every ~22µs, host have to be faster than 11ms to read sd sector) 161 | 162 | wav_player_tick_cnt <= wav_player_tick_cnt + '1'; 163 | 164 | if wav_player_tick_cnt = x"2F0" then -- ~33MHz/44.1KHz 165 | 166 | wav_player_tick_cnt <= (others => '0'); 167 | 168 | -- check for empty fifo (unrecoverable error) 169 | if tap_fifo_empty = '1' then 170 | tap_fifo_error <= '1'; 171 | else 172 | tap_fifo_rdreq <= '1'; 173 | end if; 174 | 175 | end if; 176 | cass_read <= not tap_fifo_do(7); -- only use msb (wav data is either xFF or x00/x01) 177 | 178 | end if; -- play wav mode 179 | 180 | -- tap player 181 | 182 | if (playing = '1') and (wav_mode = '0') then 183 | 184 | tap_player_tick_cnt <= tap_player_tick_cnt + '1'; 185 | 186 | -- if ((tap_player_tick_cnt = "100000") and (skip_bytes = '0')) then -- divide by 33 187 | if ((tap_player_tick_cnt = "011111") and (skip_bytes = '0')) then -- divide by 32 188 | 189 | -- square wave period (1/2 duty cycle not mandatory, only falling edge matter) 190 | if tap_version(1) = '0' then 191 | if wave_cnt > '0' & wave_len(10 downto 1) then 192 | cass_read <= '1'; 193 | else 194 | cass_read <= '0'; 195 | end if; 196 | end if; 197 | 198 | tap_player_tick_cnt <= "000000"; 199 | wave_cnt <= wave_cnt + 1; 200 | 201 | if wave_cnt = wave_len - 1 then 202 | wave_cnt <= (others => '0'); 203 | if tap_version = 2 then 204 | cass_read <= not cass_read; 205 | end if; 206 | if tap_fifo_empty = '1' then 207 | tap_fifo_error <= '1'; 208 | else 209 | tap_fifo_rdreq <= '1'; 210 | if tap_fifo_do = x"00" then 211 | wave_len <= x"000100"; -- interpret data x00 for tap version 0 212 | get_24bits_len <= tap_version(0) or tap_version(1); 213 | else 214 | wave_len <= '0'&x"000" & tap_fifo_do & "000"; 215 | end if; 216 | end if; 217 | end if; 218 | end if; -- tap_player_tick_cnt = "100000" 219 | 220 | -- catch 24bits wave_len for data x00 in tap version 1,2 221 | if (get_24bits_len = '1' ) and (skip_bytes = '0') and (tap_player_tick_cnt(0) = '1') then 222 | 223 | if tap_player_tick_cnt = "000101" then 224 | get_24bits_len <= '0'; 225 | end if; 226 | 227 | if tap_fifo_empty = '1' then 228 | tap_fifo_error <= '1'; 229 | else 230 | tap_fifo_rdreq <= '1'; 231 | wave_len <= tap_fifo_do & wave_len(23 downto 8); 232 | end if; 233 | 234 | if tap_version(1) = '0' then 235 | cass_read <= '1'; 236 | end if; 237 | end if; 238 | 239 | -- skip tap header bytes 240 | if (skip_bytes = '1' and tap_fifo_empty = '0') then 241 | tap_fifo_rdreq <= '1'; 242 | cass_read <= '1'; 243 | if start_bytes < X"14" then 244 | start_bytes <= start_bytes + X"01"; 245 | else 246 | skip_bytes <= '0'; 247 | end if; 248 | end if; 249 | 250 | end if; -- play tap 251 | 252 | end if; -- clk32 253 | end process; 254 | 255 | cass_sense <= sense; 256 | cass_run <= motor; 257 | 258 | end struct; 259 | -------------------------------------------------------------------------------- /rtl/fpga64_buslogic_roms_mmu.vhd: -------------------------------------------------------------------------------- 1 | -- ----------------------------------------------------------------------- 2 | -- 3 | -- FPGA 64 4 | -- 5 | -- A fully functional commodore 64 implementation in a single FPGA 6 | -- 7 | -- ----------------------------------------------------------------------- 8 | -- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com) 9 | -- http://www.syntiac.com/fpga64.html 10 | -- ----------------------------------------------------------------------- 11 | 12 | -- ----------------------------------------------------------------------- 13 | -- Dar 08/03/2014 14 | -- 15 | -- Based on mixing both fpga64_buslogic_roms and fpga64_buslogic_nommu 16 | -- RAM should be external SRAM 17 | -- Basic, Char and Kernel ROMs are included 18 | -- Original Kernel replaced by JiffyDos 19 | -- ----------------------------------------------------------------------- 20 | 21 | library IEEE; 22 | USE ieee.std_logic_1164.ALL; 23 | USE ieee.numeric_std.ALL; 24 | 25 | entity fpga64_buslogic is 26 | port ( 27 | clk : in std_logic; 28 | reset : in std_logic; 29 | 30 | cpuHasBus : in std_logic; 31 | aec : in std_logic; 32 | 33 | ramData: in unsigned(7 downto 0); 34 | 35 | -- 2 CHAREN 36 | -- 1 HIRAM 37 | -- 0 LORAM 38 | bankSwitch: in unsigned(2 downto 0); 39 | 40 | -- From cartridge port 41 | game : in std_logic; 42 | exrom : in std_logic; 43 | ioE_rom : in std_logic; 44 | ioF_rom : in std_logic; 45 | max_ram : in std_logic; 46 | ext_sid_cs : in std_logic; 47 | 48 | busWe: in std_logic; 49 | busAddr: in unsigned(15 downto 0); 50 | busData: in unsigned(7 downto 0); 51 | vicAddr: in unsigned(15 downto 0); 52 | vicData: in unsigned(7 downto 0); 53 | sidData: in unsigned(7 downto 0); 54 | colorData: in unsigned(3 downto 0); 55 | cia1Data: in unsigned(7 downto 0); 56 | cia2Data: in unsigned(7 downto 0); 57 | lastVicData : in unsigned(7 downto 0); 58 | 59 | systemWe: out std_logic; 60 | systemAddr: out unsigned(15 downto 0); 61 | dataToCpu : out unsigned(7 downto 0); 62 | dataToVic : out unsigned(7 downto 0); 63 | 64 | cs_vic: out std_logic; 65 | cs_sid: out std_logic; 66 | cs_color : out std_logic; 67 | cs_cia1: out std_logic; 68 | cs_cia2: out std_logic; 69 | cs_ram: out std_logic; 70 | cs_rom: out std_logic; 71 | 72 | -- To catridge port 73 | cs_ioE: out std_logic; 74 | cs_ioF: out std_logic; 75 | cs_romL : out std_logic; 76 | cs_romH : out std_logic; 77 | cs_UMAXromH : out std_logic 78 | ); 79 | end fpga64_buslogic; 80 | 81 | -- ----------------------------------------------------------------------- 82 | 83 | architecture rtl of fpga64_buslogic is 84 | component fpga64_colorram is 85 | port ( 86 | clk: in std_logic; 87 | cs: in std_logic; 88 | we: in std_logic; 89 | 90 | addr: in unsigned(9 downto 0); 91 | di: in unsigned(3 downto 0); 92 | do: out unsigned(3 downto 0) 93 | ); 94 | end component; 95 | 96 | signal charData: unsigned(7 downto 0); 97 | signal basicData: unsigned(7 downto 0); 98 | signal romData: std_logic_vector(7 downto 0); 99 | 100 | signal cs_CharReg : std_logic; 101 | signal cs_romReg : std_logic; 102 | signal vicCharReg : std_logic; 103 | 104 | signal cs_ramReg : std_logic; 105 | signal cs_vicReg : std_logic; 106 | signal cs_sidReg : std_logic; 107 | signal cs_colorReg : std_logic; 108 | signal cs_cia1Reg : std_logic; 109 | signal cs_cia2Reg : std_logic; 110 | signal cs_ioEReg : std_logic; 111 | signal cs_ioFReg : std_logic; 112 | signal cs_romLReg : std_logic; 113 | signal cs_romHReg : std_logic; 114 | signal cs_UMAXromHReg : std_logic; 115 | signal ultimax : std_logic; 116 | 117 | signal currentAddr: unsigned(15 downto 0); 118 | 119 | begin 120 | charrom: entity work.rom_c64_chargen 121 | port map ( 122 | clk => clk, 123 | addr => currentAddr(11 downto 0), 124 | do => charData 125 | ); 126 | 127 | romData <= std_logic_vector(ramData); 128 | 129 | -- 130 | --begin 131 | process(ramData, vicData, sidData, colorData, 132 | cia1Data, cia2Data, charData, romData, busData, 133 | cs_romHReg, cs_romLReg, cs_romReg, cs_CharReg, 134 | cs_ramReg, cs_vicReg, cs_sidReg, ext_sid_cs, cs_colorReg, 135 | cs_cia1Reg, cs_cia2Reg, lastVicData, 136 | cs_ioEReg, cs_ioFReg, ioE_rom, ioF_rom) 137 | begin 138 | -- If no hardware is addressed the bus is floating. 139 | -- It will contain the last data read by the VIC. (if a C64 is shielded correctly) 140 | dataToCpu <= lastVicData; 141 | if cs_CharReg = '1' then 142 | dataToCpu <= charData; 143 | elsif cs_romReg = '1' then 144 | dataToCpu <= unsigned(romData); 145 | elsif cs_ramReg = '1' then 146 | dataToCpu <= ramData; 147 | elsif cs_vicReg = '1' then 148 | dataToCpu <= vicData; 149 | elsif cs_sidReg = '1' or ext_sid_cs = '1' then 150 | dataToCpu <= sidData; 151 | elsif cs_colorReg = '1' then 152 | dataToCpu(3 downto 0) <= colorData; 153 | elsif cs_cia1Reg = '1' then 154 | dataToCpu <= cia1Data; 155 | elsif cs_cia2Reg = '1' then 156 | dataToCpu <= cia2Data; 157 | elsif cs_romLReg = '1' then 158 | dataToCpu <= ramData; 159 | elsif cs_romHReg = '1' then 160 | dataToCpu <= ramData; 161 | elsif cs_ioEReg = '1' and ioE_rom = '1' then 162 | dataToCpu <= busData; 163 | elsif cs_ioFReg = '1' and ioF_rom = '1' then 164 | dataToCpu <= busData; 165 | end if; 166 | end process; 167 | 168 | ultimax <= exrom and (not game); 169 | 170 | process(clk) 171 | begin 172 | if rising_edge(clk) then 173 | currentAddr <= (others => '1'); -- Prevent generation of a latch when neither vic or cpu is using the bus. 174 | 175 | systemWe <= '0'; 176 | vicCharReg <= '0'; 177 | cs_CharReg <= '0'; 178 | cs_romReg <= '0'; 179 | cs_ramReg <= '0'; 180 | cs_vicReg <= '0'; 181 | cs_sidReg <= '0'; 182 | cs_colorReg <= '0'; 183 | cs_cia1Reg <= '0'; 184 | cs_cia2Reg <= '0'; 185 | cs_ioEReg <= '0'; 186 | cs_ioFReg <= '0'; 187 | cs_romLReg <= '0'; 188 | cs_romHReg <= '0'; 189 | cs_UMAXromHReg <= '0'; -- Ultimax flag for the VIC access - LCA 190 | 191 | if (cpuHasBus = '1') then 192 | -- The 6502 CPU has the bus. 193 | currentAddr <= busAddr; 194 | case busAddr(15 downto 12) is 195 | when X"E" | X"F" => 196 | if ultimax = '1' and busWe = '0' then 197 | -- ULTIMAX MODE - drop out the kernal - LCA 198 | cs_romHReg <= '1'; 199 | elsif busWe = '0' and bankSwitch(1) = '1' then 200 | -- Read kernal 201 | cs_romReg <= '1'; 202 | else 203 | -- 64Kbyte RAM layout 204 | cs_ramReg <= '1'; 205 | end if; 206 | when X"D" => 207 | if (ultimax = '0' or max_ram = '1') and bankSwitch(1) = '0' and bankSwitch(0) = '0' then 208 | -- 64Kbyte RAM layout 209 | cs_ramReg <= '1'; 210 | elsif ultimax = '1' or bankSwitch(2) = '1' then 211 | case busAddr(11 downto 8) is 212 | when X"0" | X"1" | X"2" | X"3" => 213 | cs_vicReg <= '1'; 214 | when X"4" | X"5" | X"6" | X"7" => 215 | cs_sidReg <= '1'; 216 | when X"8" | X"9" | X"A" | X"B" => 217 | cs_colorReg <= '1'; 218 | when X"C" => 219 | cs_cia1Reg <= '1'; 220 | when X"D" => 221 | cs_cia2Reg <= '1'; 222 | when X"E" => 223 | cs_ioEReg <= '1'; 224 | when X"F" => 225 | cs_ioFReg <= '1'; 226 | when others => 227 | null; 228 | end case; 229 | else 230 | -- I/O space turned off. Read from charrom or write to RAM. 231 | if busWe = '0' then 232 | cs_CharReg <= '1'; 233 | else 234 | cs_ramReg <= '1'; 235 | end if; 236 | end if; 237 | when X"A" | X"B" => 238 | if exrom = '0' and game = '0' and busWe = '0' and bankSwitch(1) = '1' then 239 | -- Access cartridge with romH 240 | cs_romHReg <= '1'; 241 | elsif ultimax = '0' and busWe = '0' and bankSwitch(1) = '1' and bankSwitch(0) = '1' then 242 | -- Access basic rom 243 | -- May need turning off if kernal banked out LCA 244 | cs_romReg <= '1'; 245 | elsif ultimax = '0' or max_ram = '1' then 246 | -- If not in Ultimax mode access ram 247 | cs_ramReg <= '1'; 248 | end if; 249 | when X"8" | X"9" => 250 | if ultimax = '1' then 251 | -- Ultimax access with romL 252 | cs_romLReg <= '1'; 253 | elsif exrom = '0' and bankSwitch(1) = '1' and bankSwitch(0) = '1' then 254 | -- Access cartridge with romL 255 | cs_romLReg <= '1'; 256 | else 257 | cs_ramReg <= '1'; 258 | end if; 259 | when X"0" => 260 | cs_ramReg <= '1'; 261 | when others => 262 | -- If not in Ultimax mode access ram 263 | if ultimax = '0' or max_ram = '1' then 264 | cs_ramReg <= '1'; 265 | end if; 266 | end case; 267 | 268 | systemWe <= busWe; 269 | else 270 | -- The VIC-II has the bus, but only when aec is not asserted 271 | if aec = '0' then 272 | currentAddr <= vicAddr; 273 | else 274 | currentAddr <= busAddr; 275 | end if; 276 | 277 | if ultimax = '0' and vicAddr(14 downto 12)="001" then 278 | vicCharReg <= '1'; 279 | elsif ultimax = '1' and vicAddr(13 downto 12)="11" then 280 | -- ultimax mode changes vic addressing - LCA 281 | cs_UMAXromHReg <= '1'; 282 | else 283 | cs_ramReg <= '1'; 284 | end if; 285 | end if; 286 | end if; 287 | end process; 288 | 289 | cs_ram <= cs_ramReg or cs_romLReg or cs_romHReg or cs_UMAXromHReg; -- need to keep ram active for cartridges LCA 290 | cs_rom <= cs_romReg; 291 | cs_vic <= cs_vicReg; 292 | cs_sid <= cs_sidReg; 293 | cs_color <= cs_colorReg; 294 | cs_cia1 <= cs_cia1Reg; 295 | cs_cia2 <= cs_cia2Reg; 296 | cs_ioE <= cs_ioEReg; 297 | cs_ioF <= cs_ioFReg; 298 | cs_romL <= cs_romLReg; 299 | cs_romH <= cs_romHReg; 300 | cs_UMAXromH <= cs_UMAXromHReg; 301 | 302 | dataToVic <= charData when vicCharReg = '1' else ramData; 303 | systemAddr <= currentAddr; 304 | end architecture; 305 | -------------------------------------------------------------------------------- /rtl/reu.vhd: -------------------------------------------------------------------------------- 1 | library ieee; 2 | use ieee.std_logic_1164.all; 3 | use ieee.numeric_std.all; 4 | 5 | entity reu is 6 | port ( 7 | clock : in std_logic; 8 | reset : in std_logic; 9 | enable : in std_logic := '1'; 10 | rommask : in std_logic_vector(4 downto 0) := "11111"; 11 | 12 | -- expansion port 13 | phi : in std_logic; 14 | ba : in std_logic; 15 | iof : in std_logic; 16 | dma_n : out std_logic; 17 | addr : in std_logic_vector(15 downto 0); 18 | rnw : in std_logic; 19 | irq_n : out std_logic; 20 | din : in std_logic_vector( 7 downto 0); 21 | dout : out std_logic_vector( 7 downto 0); 22 | oe : out std_logic; -- dout output enable 23 | addr_out : out std_logic_vector(15 downto 0); 24 | rnw_out : out std_logic; 25 | 26 | -- REU RAM interface 27 | ram_addr : out std_logic_vector(23 downto 0); 28 | ram_ce : out std_logic; 29 | ram_we : out std_logic; 30 | ram_di : in std_logic_vector( 7 downto 0); 31 | ram_do : out std_logic_vector( 7 downto 0) 32 | ); 33 | end reu; 34 | 35 | architecture rtl of reu is 36 | type state_t is (idle, read_reu, write_c64, write_c64_do, read_c64, read_c64_do, write_reu, finished); 37 | signal state: state_t; 38 | 39 | signal phi_d: std_logic; 40 | signal phi_rise: std_logic; 41 | signal phi_fall: std_logic; 42 | signal phi_cnt: unsigned(3 downto 0); 43 | signal reu_cs: std_logic; 44 | signal ba_reg: std_logic; 45 | signal ba_reg2: std_logic; 46 | 47 | signal load: std_logic; 48 | signal ff00: std_logic; 49 | signal transfer_type: std_logic_vector(1 downto 0); 50 | signal c64_addr: std_logic_vector(15 downto 0); 51 | signal reu_addr: std_logic_vector(23 downto 0); 52 | signal transfer_len: std_logic_vector(15 downto 0); 53 | signal c64_start_addr: std_logic_vector(15 downto 0); 54 | signal reu_start_addr: std_logic_vector(23 downto 0); 55 | signal transfer_len_base: std_logic_vector(15 downto 0); 56 | 57 | signal reu_data: std_logic_vector(7 downto 0); 58 | signal c64_data: std_logic_vector(7 downto 0); 59 | signal reg_dout: std_logic_vector(7 downto 0); 60 | signal mem_dout: std_logic_vector(7 downto 0); 61 | 62 | signal ier: std_logic_vector(2 downto 0); 63 | signal address_ctrl: std_logic_vector(1 downto 0); 64 | signal unused: std_logic_vector(2 downto 0); 65 | 66 | signal execute: std_logic; 67 | signal transfer_end: std_logic; 68 | signal verify_error: std_logic; 69 | signal irq: std_logic; 70 | 71 | begin 72 | dout <= mem_dout when state /= idle else reg_dout; 73 | irq <= enable and ier(2) and ((ier(1) and transfer_end) or (ier(0) and verify_error)); 74 | irq_n <= not irq; 75 | 76 | process(clock) begin 77 | if rising_edge(clock) then 78 | phi_d <= phi; 79 | if (phi_rise = '1' or phi_fall = '1') then 80 | phi_cnt <= x"1"; 81 | else 82 | phi_cnt <= phi_cnt + 1; 83 | end if; 84 | end if; 85 | end process; 86 | 87 | phi_rise <= phi and not phi_d; 88 | phi_fall <= not phi and phi_d; 89 | 90 | reu_cs <= '1' when phi = '1' and iof = '1' and enable = '1' and state = idle else '0'; 91 | 92 | -- to make some timing tests (and Treu Love) happy 93 | process(clock) begin 94 | if rising_edge(clock) then 95 | if phi = '0' and phi_cnt = 1 then 96 | ba_reg <= ba; 97 | ba_reg2 <= ba_reg; 98 | end if; 99 | if ba = '1' then 100 | ba_reg <= '1'; 101 | ba_reg2 <= '1'; 102 | end if; 103 | end if; 104 | end process; 105 | 106 | -- main process 107 | process(clock, reset) begin 108 | if reset = '1' then 109 | ff00 <= '1'; 110 | load <= '0'; 111 | c64_start_addr <= x"0000"; 112 | reu_start_addr <= x"000000"; 113 | transfer_len_base <= x"FFFF"; 114 | c64_addr <= x"0000"; 115 | reu_addr <= x"000000"; 116 | transfer_len <= x"FFFF"; 117 | ier <= "000"; 118 | address_ctrl <= "00"; 119 | unused <= "000"; 120 | state <= idle; 121 | dma_n <= '1'; 122 | ram_ce <= '0'; 123 | verify_error <= '0'; 124 | transfer_end <= '0'; 125 | execute <= '0'; 126 | elsif rising_edge(clock) then 127 | if reu_cs = '1' and rnw = '0' and addr(4) = '0' then 128 | case addr(3 downto 0) is 129 | when x"1" => 130 | execute <= din(7); 131 | load <= din(5); 132 | ff00 <= din(4); 133 | transfer_type <= din(1 downto 0); 134 | unused <= din(6)&din(3 downto 2); 135 | when x"2" => 136 | c64_start_addr( 7 downto 0) <= din; 137 | c64_addr <= c64_start_addr(15 downto 8) & din; 138 | when x"3" => 139 | c64_start_addr(15 downto 8) <= din; 140 | c64_addr <= din & c64_start_addr(7 downto 0); 141 | when x"4" => 142 | reu_start_addr( 7 downto 0) <= din; 143 | reu_addr(15 downto 0) <= reu_start_addr(15 downto 8) & din; 144 | when x"5" => 145 | reu_start_addr(15 downto 8) <= din; 146 | reu_addr(15 downto 0) <= din & reu_start_addr(7 downto 0); 147 | when x"6" => 148 | reu_start_addr(23 downto 16) <= din and rommask&"111"; 149 | reu_addr(23 downto 16) <= din and rommask&"111"; 150 | when x"7" => 151 | transfer_len_base( 7 downto 0) <= din; 152 | transfer_len <= transfer_len_base(15 downto 8) & din; 153 | when x"8" => 154 | transfer_len_base(15 downto 8) <= din; 155 | transfer_len <= din & transfer_len_base(7 downto 0); 156 | when x"9" => ier <= din(7 downto 5); 157 | when x"A" => address_ctrl <= din(7 downto 6); 158 | when others => null; 159 | end case; 160 | end if; 161 | 162 | -- status register read clears interrupt flags 163 | if reu_cs = '1' and rnw = '1' and addr(4 downto 0) = '0'&x"0" and phi_cnt = 15 then 164 | transfer_end <= '0'; 165 | verify_error <= '0'; 166 | end if; 167 | 168 | case state is 169 | when idle => 170 | if phi = '1' and phi_cnt = 15 and execute = '1' and 171 | (ff00 = '1' or addr = x"ff00") 172 | then 173 | execute <= '0'; 174 | dma_n <= '0'; 175 | if transfer_type = "00" then 176 | state <= read_c64; 177 | else 178 | state <= read_reu; 179 | end if; 180 | end if; 181 | 182 | when read_reu => 183 | ram_addr <= reu_addr and (rommask & "111" & x"FFFF"); 184 | ram_we <= '0'; 185 | if phi = '0' and phi_cnt = 7 then 186 | ram_ce <= '1'; 187 | end if; 188 | if phi = '0' and phi_cnt = 10 then 189 | ram_ce <= '0'; 190 | end if; 191 | if phi = '0' and phi_cnt = 11 then 192 | reu_data <= ram_di; 193 | if address_ctrl(0) = '0' and transfer_type /= "10" then 194 | reu_addr <= std_logic_vector(unsigned(reu_addr) + 1) and (rommask & "111" & x"FFFF"); 195 | end if; 196 | if transfer_type(1) = '1' then -- swap, verify 197 | state <= read_c64; 198 | else 199 | state <= write_c64; 200 | end if; 201 | end if; 202 | 203 | when write_c64 => 204 | if phi = '0' then 205 | if ba_reg2 = '1' then 206 | state <= write_c64_do; 207 | end if; 208 | end if; 209 | 210 | when write_c64_do => 211 | mem_dout <= reu_data; 212 | addr_out <= c64_addr; 213 | rnw_out <= '0'; 214 | if phi = '1' and phi_cnt = 15 then 215 | rnw_out <= '1'; 216 | if address_ctrl(1) = '0' then 217 | c64_addr <= std_logic_vector(unsigned(c64_addr) + 1); 218 | end if; 219 | if transfer_len = x"0001" then 220 | state <= finished; 221 | else 222 | transfer_len <= std_logic_vector(unsigned(transfer_len) - 1); 223 | state <= read_reu; 224 | end if; 225 | end if; 226 | 227 | when read_c64 => 228 | rnw_out <= '1'; 229 | if phi = '0' then 230 | if ba_reg2 = '1' then 231 | state <= read_c64_do; 232 | end if; 233 | end if; 234 | 235 | when read_c64_do => 236 | addr_out <= c64_addr; 237 | rnw_out <= '1'; 238 | if phi = '1' and phi_cnt = 15 then 239 | c64_data <= din; 240 | if address_ctrl(1) = '0' and transfer_type /= "10" then 241 | c64_addr <= std_logic_vector(unsigned(c64_addr) + 1); 242 | end if; 243 | if transfer_type = "11" then -- verify 244 | if transfer_len = x"0001" then 245 | state <= finished; 246 | else 247 | transfer_len <= std_logic_vector(unsigned(transfer_len) - 1); 248 | state <= read_reu; 249 | end if; 250 | if reu_data /= din then 251 | verify_error <= '1'; 252 | state <= finished; 253 | end if; 254 | else 255 | state <= write_reu; 256 | end if; 257 | end if; 258 | 259 | when write_reu => 260 | ram_addr <= reu_addr and (rommask & "111" & x"FFFF"); 261 | ram_we <= '1'; 262 | ram_do <= c64_data; 263 | if phi = '0' and phi_cnt = 7 then 264 | ram_ce <= '1'; 265 | end if; 266 | if phi = '0' and phi_cnt = 10 then 267 | ram_ce <= '0'; 268 | end if; 269 | if phi = '0' and phi_cnt = 11 then 270 | if address_ctrl(0) = '0' then 271 | reu_addr <= std_logic_vector(unsigned(reu_addr) + 1) and (rommask & "111" & x"FFFF"); 272 | end if; 273 | if transfer_type = "10" then -- swap 274 | state <= write_c64; 275 | elsif transfer_len = x"0001" then 276 | state <= finished; 277 | else 278 | transfer_len <= std_logic_vector(unsigned(transfer_len) - 1); 279 | state <= read_c64; 280 | end if; 281 | end if; 282 | 283 | when finished => 284 | if phi = '0' and phi_cnt = 0 and ba = '1' then 285 | dma_n <= '1'; 286 | ff00 <= '1'; 287 | if not (verify_error = '1' and transfer_len /= x"0001") then 288 | transfer_end <= '1'; 289 | if load = '1' then 290 | c64_addr <= c64_start_addr; 291 | reu_addr <= reu_start_addr and (rommask & "111" & x"FFFF"); 292 | transfer_len <= transfer_len_base; 293 | end if; 294 | end if; 295 | state <= idle; 296 | end if; 297 | end case; 298 | end if; 299 | end process; 300 | 301 | process(addr, transfer_end, verify_error, execute, load, ff00, 302 | transfer_type, c64_addr, reu_addr, transfer_len, ier, address_ctrl, unused, rommask, irq) 303 | begin 304 | case addr(4 downto 0) is 305 | when '0'&x"0" => reg_dout <= irq&transfer_end&verify_error&'1'&x"0"; 306 | when '0'&x"1" => reg_dout <= execute&unused(2)&load&ff00&unused(1 downto 0)&transfer_type; 307 | when '0'&x"2" => reg_dout <= c64_addr( 7 downto 0); 308 | when '0'&x"3" => reg_dout <= c64_addr(15 downto 8); 309 | when '0'&x"4" => reg_dout <= reu_addr( 7 downto 0); 310 | when '0'&x"5" => reg_dout <= reu_addr(15 downto 8); 311 | when '0'&x"6" => reg_dout <= reu_addr(23 downto 16) or not (rommask & "111"); 312 | when '0'&x"7" => reg_dout <= transfer_len( 7 downto 0); 313 | when '0'&x"8" => reg_dout <= transfer_len(15 downto 8); 314 | when '0'&x"9" => reg_dout <= ier&"11111"; 315 | when '0'&x"A" => reg_dout <= address_ctrl&"111111"; 316 | when others => reg_dout <= x"FF"; 317 | end case; 318 | end process; 319 | 320 | oe <= '1' when (reu_cs = '1' and rnw = '1') or state = write_c64_do else '0'; 321 | 322 | end rtl; 323 | --------------------------------------------------------------------------------