├── 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 |
--------------------------------------------------------------------------------