mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-03-10 20:33:41 +00:00
add new SID
This commit is contained in:
@@ -41,9 +41,8 @@
|
||||
# ========================
|
||||
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 13.1
|
||||
set_global_assignment -name PROJECT_CREATION_TIME_DATE "21:40:24 MAY 17, 2014"
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION "13.0 SP1"
|
||||
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
|
||||
set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL
|
||||
set_global_assignment -name SMART_RECOMPILE ON
|
||||
set_global_assignment -name FLOW_ENABLE_IO_ASSIGNMENT_ANALYSIS ON
|
||||
|
||||
@@ -312,59 +311,53 @@ set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to CONF_DATA0
|
||||
|
||||
# Incremental Compilation Assignments
|
||||
# ===================================
|
||||
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
|
||||
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
|
||||
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
|
||||
# end DESIGN_PARTITION(Top)
|
||||
# -------------------------
|
||||
|
||||
# end ENTITY(C64_MiST)
|
||||
# ----------------------
|
||||
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
|
||||
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
|
||||
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
set_global_assignment -name VERILOG_FILE rtl/1541/trkbuf.v
|
||||
set_global_assignment -name VHDL_FILE rtl/1541/rom_C1541.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/1541/c1541_sd.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/1541/c1541_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/1541/c1541_logic.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/c64_mist.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sid/wave_map.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sid/sid_top.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sid/sid_regs.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sid/sid_mixer.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sid/sid_filter.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sid/sid_debug_pkg.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sid/sid_ctrl.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sid/Q_table.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sid/oscillator.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sid/my_math_pkg.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sid/mult_acc.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/sid/adsr_multi.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/fpga64_sid_iec.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/video_vicII_656x_e.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/video_vicII_656x_a.vhd
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/video_mixer.sv
|
||||
set_global_assignment -name VERILOG_FILE rtl/trkbuf.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/sigma_delta_dac.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/sdram.v
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/sd_card.sv
|
||||
set_global_assignment -name VERILOG_FILE rtl/scandoubler.v
|
||||
set_global_assignment -name VHDL_FILE rtl/rom_C1541.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/rom_c64_chargen.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/rom_C64.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/pll.vhd
|
||||
set_global_assignment -name VERILOG_FILE rtl/osd.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/mist_io.v
|
||||
set_global_assignment -name VHDL_FILE rtl/m6522.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/io_ps2_keyboard.vhd
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/hq2x.sv
|
||||
set_global_assignment -name VHDL_FILE rtl/gen_ram.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/gcr_floppy.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/fpga64_sid_iec.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/fpga64_rgbcolor.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/fpga64_keyboard_matrix_mark_mcdougall.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/fpga64_bustiming.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/fpga64_buslogic_roms_mmu.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu65xx_fast.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu65xx_e.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu_6510.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/composite_sync.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cia6526.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu_6510.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/m6522.vhd
|
||||
set_global_assignment -name VERILOG_FILE rtl/cartridge.v
|
||||
set_global_assignment -name VHDL_FILE rtl/c1541_sd.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/c1541_logic.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/rom_c64_chargen.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/rom_C64.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/rom_GS64.vhd
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/sid8580.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/sid_voice.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/sid_filters.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/sid_envelope.sv
|
||||
set_global_assignment -name VERILOG_FILE rtl/sigma_delta_dac.v
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/video_mixer.sv
|
||||
set_global_assignment -name VERILOG_FILE rtl/sdram.v
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/sd_card.sv
|
||||
set_global_assignment -name VERILOG_FILE rtl/scandoubler.v
|
||||
set_global_assignment -name VHDL_FILE rtl/pll.vhd
|
||||
set_global_assignment -name VERILOG_FILE rtl/osd.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/mist_io.v
|
||||
set_global_assignment -name VHDL_FILE rtl/io_ps2_keyboard.vhd
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/hq2x.sv
|
||||
set_global_assignment -name VHDL_FILE rtl/gen_ram.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/composite_sync.vhd
|
||||
set_global_assignment -name TEXT_FILE ../Text1.txt
|
||||
set_global_assignment -name VHDL_FILE rtl/1541/gcr_floppy.vhd
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
6
Commodore - 64_MiST/C64_mist.srf
Normal file
6
Commodore - 64_MiST/C64_mist.srf
Normal file
@@ -0,0 +1,6 @@
|
||||
{ "" "" "" "Verilog HDL macro warning at hq2x.sv(26): overriding existing definition for macro \"BITS_TO_FIT\", which was defined in \"rtl/scandoubler.v\", line 109" { } { } 0 10274 "" 0 0 "Quartus II" 0 -1 0 ""}
|
||||
{ "" "" "" "Verilog HDL warning at hq2x.sv(247): extended using \"x\" or \"z\"" { } { } 0 10273 "" 0 0 "Quartus II" 0 -1 0 ""}
|
||||
{ "" "" "" "Verilog HDL information at scandoubler.v(102): always construct contains both blocking and non-blocking assignments" { } { } 0 10268 "" 0 0 "Quartus II" 0 -1 0 ""}
|
||||
{ "" "" "" "2 hierarchies have connectivity warnings - see the Connectivity Checks report folder" { } { } 0 12241 "" 0 0 "Quartus II" 0 -1 0 ""}
|
||||
{ "" "" "" "*" { } { } 0 10230 "" 0 0 "Quartus II" 0 -1 0 ""}
|
||||
{ "" "" "" "*" { } { } 0 332060 "" 0 0 "Quartus II" 0 -1 0 ""}
|
||||
Binary file not shown.
Binary file not shown.
51
Commodore - 64_MiST/rtl/1541/c1541_rom.vhd
Normal file
51
Commodore - 64_MiST/rtl/1541/c1541_rom.vhd
Normal file
@@ -0,0 +1,51 @@
|
||||
library ieee;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.std_logic_unsigned.ALL;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
entity c1541_rom is
|
||||
port
|
||||
(
|
||||
wrclock : in std_logic;
|
||||
wraddress : in std_logic_vector(13 downto 0);
|
||||
data : in std_logic_vector(7 downto 0);
|
||||
wren : in std_logic := '0';
|
||||
|
||||
rdclock : in std_logic;
|
||||
rdaddress : in std_logic_vector(13 downto 0);
|
||||
q : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
|
||||
end;
|
||||
|
||||
architecture rtl of c1541_rom is
|
||||
|
||||
subtype word_t is std_logic_vector(7 downto 0);
|
||||
type memory_t is array(16383 downto 0) of word_t;
|
||||
|
||||
shared variable ram : memory_t;
|
||||
|
||||
attribute ram_init_file : string;
|
||||
attribute ram_init_file of ram : variable is "c1541/c1541_rom.mif";
|
||||
|
||||
begin
|
||||
|
||||
-- Port A
|
||||
process(wrclock)
|
||||
begin
|
||||
if(rising_edge(wrclock)) then
|
||||
if(wren = '1') then
|
||||
ram(to_integer(unsigned(wraddress))) := data;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Port B
|
||||
process(rdclock)
|
||||
begin
|
||||
if(rising_edge(rdclock)) then
|
||||
q <= ram(to_integer(unsigned(rdaddress)));
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end rtl;
|
||||
18
Commodore - 64_MiST/rtl/c1541/c1541.qip
Normal file
18
Commodore - 64_MiST/rtl/c1541/c1541.qip
Normal file
@@ -0,0 +1,18 @@
|
||||
set_global_assignment -name VHDL_FILE c1541/cpu/shifter.vhd
|
||||
set_global_assignment -name VHDL_FILE c1541/cpu/proc_registers.vhd
|
||||
set_global_assignment -name VHDL_FILE c1541/cpu/proc_interrupt.vhd
|
||||
set_global_assignment -name VHDL_FILE c1541/cpu/proc_control.vhd
|
||||
set_global_assignment -name VHDL_FILE c1541/cpu/pkg_6502_opcodes.vhd
|
||||
set_global_assignment -name VHDL_FILE c1541/cpu/pkg_6502_defs.vhd
|
||||
set_global_assignment -name VHDL_FILE c1541/cpu/pkg_6502_decode.vhd
|
||||
set_global_assignment -name VHDL_FILE c1541/cpu/implied.vhd
|
||||
set_global_assignment -name VHDL_FILE c1541/cpu/data_oper.vhd
|
||||
set_global_assignment -name VHDL_FILE c1541/cpu/bit_cpx_cpy.vhd
|
||||
set_global_assignment -name VHDL_FILE c1541/cpu/alu.vhd
|
||||
set_global_assignment -name VHDL_FILE c1541/cpu/proc_core.vhd
|
||||
set_global_assignment -name VHDL_FILE c1541/c1541_via6522.vhd
|
||||
set_global_assignment -name VHDL_FILE c1541/c1541_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE c1541/gcr_floppy.vhd
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE c1541/c1541_track.sv
|
||||
set_global_assignment -name VHDL_FILE c1541/c1541_logic.vhd
|
||||
set_global_assignment -name VHDL_FILE c1541/c1541_sd.vhd
|
||||
301
Commodore - 64_MiST/rtl/c1541/c1541_logic.vhd
Normal file
301
Commodore - 64_MiST/rtl/c1541/c1541_logic.vhd
Normal file
@@ -0,0 +1,301 @@
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
--
|
||||
-- Model 1541B
|
||||
--
|
||||
entity c1541_logic is
|
||||
port
|
||||
(
|
||||
clk_32M : in std_logic;
|
||||
reset : in std_logic;
|
||||
|
||||
-- serial bus
|
||||
sb_data_oe : out std_logic;
|
||||
sb_data_in : in std_logic;
|
||||
sb_clk_oe : out std_logic;
|
||||
sb_clk_in : in std_logic;
|
||||
sb_atn_in : in std_logic;
|
||||
|
||||
c1541rom_clk : in std_logic;
|
||||
c1541rom_addr : in std_logic_vector(13 downto 0);
|
||||
c1541rom_data : in std_logic_vector(7 downto 0);
|
||||
c1541rom_wr : in std_logic;
|
||||
|
||||
-- drive-side interface
|
||||
ds : in std_logic_vector(1 downto 0); -- device select
|
||||
di : in std_logic_vector(7 downto 0); -- disk read data
|
||||
do : out std_logic_vector(7 downto 0); -- disk write data
|
||||
mode : out std_logic; -- read/write
|
||||
stp : out std_logic_vector(1 downto 0); -- stepper motor control
|
||||
mtr : out std_logic; -- stepper motor on/off
|
||||
freq : out std_logic_vector(1 downto 0); -- motor frequency
|
||||
sync_n : in std_logic; -- reading SYNC bytes
|
||||
byte_n : in std_logic; -- byte ready
|
||||
wps_n : in std_logic; -- write-protect sense
|
||||
tr00_sense_n : in std_logic; -- track 0 sense (unused?)
|
||||
act : out std_logic -- activity LED
|
||||
);
|
||||
end c1541_logic;
|
||||
|
||||
architecture SYN of c1541_logic is
|
||||
|
||||
-- clocks
|
||||
signal p2_h_r : std_logic;
|
||||
signal p2_h_f : std_logic;
|
||||
|
||||
-- cpu signals
|
||||
signal cpu_a : std_logic_vector(16 downto 0);
|
||||
signal cpu_di : std_logic_vector(7 downto 0);
|
||||
signal cpu_do : std_logic_vector(7 downto 0);
|
||||
signal cpu_rw : std_logic;
|
||||
signal cpu_irq_n : std_logic;
|
||||
signal cpu_so_n : std_logic;
|
||||
|
||||
-- rom signals
|
||||
signal rom_cs : std_logic;
|
||||
signal rom_do : std_logic_vector(cpu_di'range);
|
||||
|
||||
-- ram signals
|
||||
signal ram_cs : std_logic;
|
||||
signal ram_wr : std_logic;
|
||||
signal ram_do : std_logic_vector(cpu_di'range);
|
||||
|
||||
-- UC1 (VIA6522) signals
|
||||
signal uc1_do : std_logic_vector(7 downto 0);
|
||||
signal uc1_cs : std_logic;
|
||||
signal uc1_irq_n : std_logic;
|
||||
signal uc1_pa_i : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal uc1_pb_i : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal uc1_pb_o : std_logic_vector(7 downto 0);
|
||||
signal uc1_pb_oe_n : std_logic_vector(7 downto 0);
|
||||
|
||||
-- UC3 (VIA6522) signals
|
||||
signal uc3_do : std_logic_vector(7 downto 0);
|
||||
signal uc3_cs : std_logic;
|
||||
signal uc3_irq_n : std_logic;
|
||||
signal uc3_ca1_i : std_logic;
|
||||
signal uc3_ca2_o : std_logic;
|
||||
signal uc3_ca2_oe_n : std_logic;
|
||||
signal uc3_pa_i : std_logic_vector(7 downto 0);
|
||||
signal uc3_pa_o : std_logic_vector(7 downto 0);
|
||||
signal uc3_cb2_o : std_logic;
|
||||
signal uc3_cb2_oe_n : std_logic;
|
||||
signal uc3_pa_oe_n : std_logic_vector(7 downto 0);
|
||||
signal uc3_pb_i : std_logic_vector(7 downto 0);
|
||||
signal uc3_pb_o : std_logic_vector(7 downto 0);
|
||||
signal uc3_pb_oe_n : std_logic_vector(7 downto 0);
|
||||
|
||||
-- internal signals
|
||||
signal atna : std_logic; -- ATN ACK - input gate array
|
||||
signal atn : std_logic; -- attention
|
||||
signal soe : std_logic; -- set overflow enable
|
||||
|
||||
type t_byte_array is array(2047 downto 0) of std_logic_vector(7 downto 0);
|
||||
signal ram : t_byte_array;
|
||||
|
||||
signal sb_data : std_logic;
|
||||
signal sb_clk : std_logic;
|
||||
|
||||
signal iec_atn_d1 : std_logic;
|
||||
signal iec_data_d1 : std_logic;
|
||||
signal iec_clk_d1 : std_logic;
|
||||
signal iec_atn_d2 : std_logic;
|
||||
signal iec_data_d2 : std_logic;
|
||||
signal iec_clk_d2 : std_logic;
|
||||
signal iec_atn : std_logic;
|
||||
signal iec_data : std_logic;
|
||||
signal iec_clk : std_logic;
|
||||
|
||||
begin
|
||||
process (clk_32M) begin
|
||||
if rising_edge(clk_32M) then
|
||||
iec_atn_d1 <=sb_atn_in;
|
||||
iec_atn_d2 <=iec_atn_d1;
|
||||
iec_atn <=iec_atn_d2;
|
||||
|
||||
iec_data_d1<=sb_data_in;
|
||||
iec_data_d2<=iec_data_d1;
|
||||
iec_data <=iec_data_d2;
|
||||
|
||||
iec_clk_d1 <=sb_clk_in;
|
||||
iec_clk_d2 <=iec_clk_d1;
|
||||
iec_clk <=iec_clk_d2;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process (clk_32M, reset)
|
||||
variable count : std_logic_vector(4 downto 0) := (others => '0');
|
||||
begin
|
||||
if rising_edge(clk_32M) then
|
||||
count := std_logic_vector(unsigned(count) + 1);
|
||||
|
||||
p2_h_r <= '0'; if count = "00000" then p2_h_r <= '1'; end if;
|
||||
p2_h_f <= '0'; if count = "10000" then p2_h_f <= '1'; end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- decode logic
|
||||
ram_cs <= '1' when STD_MATCH(cpu_a(15 downto 0), "00000-----------") else '0'; -- RAM $0000-$07FF (2KB)
|
||||
uc1_cs <= '1' when STD_MATCH(cpu_a(15 downto 0), "000110000000----") else '0'; -- UC1 $1800-$180F
|
||||
uc3_cs <= '1' when STD_MATCH(cpu_a(15 downto 0), "000111000000----") else '0'; -- UC3 $1C00-$1C0F
|
||||
rom_cs <= '1' when STD_MATCH(cpu_a(15 downto 0), "11--------------") else '0'; -- ROM $C000-$FFFF (16KB)
|
||||
|
||||
-- qualified write signals
|
||||
ram_wr <= '1' when ram_cs = '1' and cpu_rw = '0' else '0';
|
||||
|
||||
--
|
||||
-- hook up UC1 ports
|
||||
--
|
||||
sb_data <= (uc1_pb_o(1) and not uc1_pb_oe_n(1)) or atn;
|
||||
sb_clk <= uc1_pb_o(3) and not uc1_pb_oe_n(3);
|
||||
atna <= uc1_pb_o(4);
|
||||
|
||||
uc1_pa_i(0) <= tr00_sense_n;
|
||||
uc1_pb_i(0) <= not iec_data or sb_data;
|
||||
uc1_pb_i(2) <= not iec_clk or sb_clk;
|
||||
uc1_pb_i(7) <= not iec_atn;
|
||||
uc1_pb_i(6 downto 5) <= ds;
|
||||
|
||||
sb_data_oe <= sb_data;
|
||||
sb_clk_oe <= sb_clk;
|
||||
|
||||
--
|
||||
-- hook up UC3 ports
|
||||
--
|
||||
uc3_ca1_i <= cpu_so_n; -- byte ready gated with soe
|
||||
soe <= uc3_ca2_o or uc3_ca2_oe_n;
|
||||
uc3_pa_i <= di;
|
||||
do <= uc3_pa_o or uc3_pa_oe_n;
|
||||
mode <= uc3_cb2_o or uc3_cb2_oe_n;
|
||||
|
||||
stp(1) <= uc3_pb_o(0) or uc3_pb_oe_n(0);
|
||||
stp(0) <= uc3_pb_o(1) or uc3_pb_oe_n(1);
|
||||
mtr <= uc3_pb_o(2) or uc3_pb_oe_n(2);
|
||||
act <= uc3_pb_o(3) or uc3_pb_oe_n(3);
|
||||
freq <= uc3_pb_o(6 downto 5) or uc3_pb_oe_n(6 downto 5);
|
||||
uc3_pb_i <= sync_n & "11" & wps_n & "1111";
|
||||
|
||||
--
|
||||
-- CPU connections
|
||||
--
|
||||
cpu_di <= rom_do when rom_cs = '1' else
|
||||
ram_do when ram_cs = '1' else
|
||||
uc1_do when uc1_cs = '1' else
|
||||
uc3_do when uc3_cs = '1' else
|
||||
(others => '1');
|
||||
|
||||
cpu_irq_n <= uc1_irq_n and uc3_irq_n;
|
||||
cpu_so_n <= byte_n or not soe;
|
||||
|
||||
-- internal connections
|
||||
atn <= atna xor (not sb_atn_in);
|
||||
|
||||
cpu: work.proc_core
|
||||
port map(
|
||||
reset => reset,
|
||||
clock_en => p2_h_f,
|
||||
clock => clk_32M,
|
||||
so_n => cpu_so_n,
|
||||
irq_n => cpu_irq_n,
|
||||
read_write_n => cpu_rw,
|
||||
addr_out => cpu_a,
|
||||
data_in => cpu_di,
|
||||
data_out => cpu_do
|
||||
);
|
||||
|
||||
rom_inst: entity work.C1541_rom
|
||||
port map (
|
||||
wrclock => c1541rom_clk,
|
||||
|
||||
wren => c1541rom_wr,
|
||||
data => c1541rom_data,
|
||||
wraddress => c1541rom_addr,
|
||||
|
||||
rdclock => clk_32M,
|
||||
rdaddress => cpu_a(13 downto 0),
|
||||
q => rom_do
|
||||
);
|
||||
|
||||
process (clk_32M)
|
||||
begin
|
||||
if rising_edge(clk_32M) then
|
||||
ram_do <= ram(to_integer(unsigned(cpu_a(13 downto 0))));
|
||||
if ram_wr = '1' then
|
||||
ram(to_integer(unsigned(cpu_a(13 downto 0)))) <= cpu_do;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
uc1_via6522_inst : entity work.c1541_via6522
|
||||
port map
|
||||
(
|
||||
addr => cpu_a(3 downto 0),
|
||||
data_in => cpu_do,
|
||||
data_out => uc1_do,
|
||||
|
||||
ren => cpu_rw and uc1_cs,
|
||||
wen => not cpu_rw and uc1_cs,
|
||||
|
||||
irq_l => uc1_irq_n,
|
||||
|
||||
-- port a
|
||||
ca1_i => not sb_atn_in,
|
||||
ca2_i => '0',
|
||||
|
||||
port_a_i => uc1_pa_i,
|
||||
|
||||
-- port b
|
||||
cb1_i => '0',
|
||||
cb2_i => '0',
|
||||
|
||||
port_b_i => uc1_pb_i,
|
||||
port_b_o => uc1_pb_o,
|
||||
port_b_t_l => uc1_pb_oe_n,
|
||||
|
||||
reset => reset,
|
||||
clock => clk_32M,
|
||||
rising => p2_h_r,
|
||||
falling => p2_h_f
|
||||
);
|
||||
|
||||
uc3_via6522_inst : entity work.c1541_via6522
|
||||
port map
|
||||
(
|
||||
addr => cpu_a(3 downto 0),
|
||||
data_in => cpu_do,
|
||||
data_out => uc3_do,
|
||||
|
||||
ren => cpu_rw and uc3_cs,
|
||||
wen => not cpu_rw and uc3_cs,
|
||||
|
||||
irq_l => uc3_irq_n,
|
||||
|
||||
-- port a
|
||||
ca1_i => uc3_ca1_i,
|
||||
ca2_i => '0',
|
||||
ca2_o => uc3_ca2_o,
|
||||
ca2_t_l => uc3_ca2_oe_n,
|
||||
|
||||
port_a_i => uc3_pa_i,
|
||||
port_a_o => uc3_pa_o,
|
||||
port_a_t_l => uc3_pa_oe_n,
|
||||
|
||||
-- port b
|
||||
cb1_i => '0',
|
||||
cb2_i => '0',
|
||||
cb2_o => uc3_cb2_o,
|
||||
cb2_t_l => uc3_cb2_oe_n,
|
||||
|
||||
port_b_i => uc3_pb_i,
|
||||
port_b_o => uc3_pb_o,
|
||||
port_b_t_l => uc3_pb_oe_n,
|
||||
|
||||
reset => reset,
|
||||
clock => clk_32M,
|
||||
rising => p2_h_r,
|
||||
falling => p2_h_f
|
||||
);
|
||||
|
||||
end SYN;
|
||||
15762
Commodore - 64_MiST/rtl/c1541/c1541_rom.mif
Normal file
15762
Commodore - 64_MiST/rtl/c1541/c1541_rom.mif
Normal file
File diff suppressed because it is too large
Load Diff
51
Commodore - 64_MiST/rtl/c1541/c1541_rom.vhd
Normal file
51
Commodore - 64_MiST/rtl/c1541/c1541_rom.vhd
Normal file
@@ -0,0 +1,51 @@
|
||||
library ieee;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.std_logic_unsigned.ALL;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
entity c1541_rom is
|
||||
port
|
||||
(
|
||||
wrclock : in std_logic;
|
||||
wraddress : in std_logic_vector(13 downto 0);
|
||||
data : in std_logic_vector(7 downto 0);
|
||||
wren : in std_logic := '0';
|
||||
|
||||
rdclock : in std_logic;
|
||||
rdaddress : in std_logic_vector(13 downto 0);
|
||||
q : out std_logic_vector(7 downto 0)
|
||||
);
|
||||
|
||||
end;
|
||||
|
||||
architecture rtl of c1541_rom is
|
||||
|
||||
subtype word_t is std_logic_vector(7 downto 0);
|
||||
type memory_t is array(16383 downto 0) of word_t;
|
||||
|
||||
shared variable ram : memory_t;
|
||||
|
||||
attribute ram_init_file : string;
|
||||
attribute ram_init_file of ram : variable is "c1541/c1541_rom.mif";
|
||||
|
||||
begin
|
||||
|
||||
-- Port A
|
||||
process(wrclock)
|
||||
begin
|
||||
if(rising_edge(wrclock)) then
|
||||
if(wren = '1') then
|
||||
ram(to_integer(unsigned(wraddress))) := data;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Port B
|
||||
process(rdclock)
|
||||
begin
|
||||
if(rising_edge(rdclock)) then
|
||||
q <= ram(to_integer(unsigned(rdaddress)));
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end rtl;
|
||||
279
Commodore - 64_MiST/rtl/c1541/c1541_sd.vhd
Normal file
279
Commodore - 64_MiST/rtl/c1541/c1541_sd.vhd
Normal file
@@ -0,0 +1,279 @@
|
||||
---------------------------------------------------------------------------------
|
||||
--
|
||||
-- Reworked and adapted to MiSTer by Sorgelig@MiSTer (31.08.2018)
|
||||
--
|
||||
-- Commodore 1541 to SD card by Dar (darfpga@aol.fr)
|
||||
-- http://darfpga.blogspot.fr
|
||||
--
|
||||
-- c1541_logic from : Mark McDougall
|
||||
-- via6522 from : Gideon Zweijtzer <gideon.zweijtzer@gmail.com>
|
||||
-- cpu from : Gideon Zweijtzer <gideon.zweijtzer@gmail.com>
|
||||
-- c1541_track from : Sorgelig@MiSTer
|
||||
--
|
||||
-- c1541_logic modified for : slow down CPU (EOI ack missed by real c64)
|
||||
-- : remove iec internal OR wired
|
||||
-- : synched atn_in (sometime no IRQ with real c64)
|
||||
--
|
||||
-- Input clk 32MHz
|
||||
--
|
||||
---------------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.std_logic_unsigned.ALL;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
entity c1541_sd is
|
||||
port
|
||||
(
|
||||
clk32 : in std_logic;
|
||||
|
||||
disk_change : in std_logic;
|
||||
disk_readonly : in std_logic;
|
||||
drive_num : in std_logic_vector(1 downto 0) := "00";
|
||||
|
||||
iec_reset_i : in std_logic;
|
||||
iec_atn_i : in std_logic;
|
||||
iec_data_i : in std_logic;
|
||||
iec_clk_i : in std_logic;
|
||||
iec_data_o : out std_logic;
|
||||
iec_clk_o : out std_logic;
|
||||
|
||||
sd_lba : out std_logic_vector(31 downto 0);
|
||||
sd_rd : out std_logic;
|
||||
sd_wr : out std_logic;
|
||||
sd_ack : in std_logic;
|
||||
|
||||
sd_buff_addr : in std_logic_vector(8 downto 0);
|
||||
sd_buff_dout : in std_logic_vector(7 downto 0);
|
||||
sd_buff_din : out std_logic_vector(7 downto 0);
|
||||
sd_buff_wr : in std_logic;
|
||||
|
||||
led : out std_logic;
|
||||
|
||||
c1541rom_clk : in std_logic;
|
||||
c1541rom_addr : in std_logic_vector(13 downto 0);
|
||||
c1541rom_data : in std_logic_vector(7 downto 0);
|
||||
c1541rom_wr : in std_logic
|
||||
);
|
||||
end;
|
||||
|
||||
architecture struct of c1541_sd is
|
||||
|
||||
component c1541_track port
|
||||
(
|
||||
sd_lba : out std_logic_vector(31 downto 0);
|
||||
sd_rd : out std_logic;
|
||||
sd_wr : out std_logic;
|
||||
sd_ack : in std_logic;
|
||||
|
||||
sd_buff_addr : in std_logic_vector(8 downto 0);
|
||||
sd_buff_dout : in std_logic_vector(7 downto 0);
|
||||
sd_buff_din : out std_logic_vector(7 downto 0);
|
||||
sd_buff_wr : in std_logic;
|
||||
|
||||
buff_addr : in std_logic_vector(7 downto 0);
|
||||
buff_dout : out std_logic_vector(7 downto 0);
|
||||
buff_din : in std_logic_vector(7 downto 0);
|
||||
buff_we : in std_logic;
|
||||
|
||||
save_track : in std_logic;
|
||||
change : in std_logic; -- Force reload as disk may have changed
|
||||
track : in std_logic_vector(5 downto 0); -- Track number (0-34)
|
||||
sector : in std_logic_vector(4 downto 0); -- Sector number (0-20)
|
||||
busy : out std_logic;
|
||||
|
||||
clk : in std_logic; -- System clock
|
||||
reset : in std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
signal buff_dout : std_logic_vector(7 downto 0);
|
||||
signal buff_din : std_logic_vector(7 downto 0);
|
||||
signal buff_we : std_logic;
|
||||
signal do : std_logic_vector(7 downto 0); -- disk read data
|
||||
signal di : std_logic_vector(7 downto 0); -- disk write data
|
||||
signal mode : std_logic; -- read/write
|
||||
signal stp : std_logic_vector(1 downto 0); -- stepper motor control
|
||||
signal stp_r : std_logic_vector(1 downto 0); -- stepper motor control
|
||||
signal mtr : std_logic; -- stepper motor on/off
|
||||
signal sync_n : std_logic; -- reading SYNC bytes
|
||||
signal byte_n : std_logic; -- byte ready
|
||||
signal act : std_logic; -- activity LED
|
||||
signal act_r : std_logic;
|
||||
signal sd_busy : std_logic;
|
||||
signal sector : std_logic_vector(4 downto 0);
|
||||
signal byte_addr : std_logic_vector(7 downto 0);
|
||||
signal track_num_dbl : std_logic_vector(6 downto 0);
|
||||
signal track : std_logic_vector(5 downto 0);
|
||||
|
||||
signal tr00_sense_n : std_logic;
|
||||
signal save_track : std_logic;
|
||||
signal track_modified : std_logic;
|
||||
|
||||
signal ch_timeout : integer := 0;
|
||||
signal prev_change : std_logic := '0';
|
||||
signal ch_state : std_logic := '0';
|
||||
|
||||
signal reset, reset_r : std_logic;
|
||||
begin
|
||||
|
||||
tr00_sense_n <= '1' when (track > "000000") else '0';
|
||||
|
||||
process(clk32) begin
|
||||
if rising_edge(clk32) then
|
||||
reset_r <= iec_reset_i;
|
||||
reset <= reset_r;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process(clk32) begin
|
||||
if rising_edge(clk32) then
|
||||
prev_change <= disk_change;
|
||||
if ch_timeout > 0 then
|
||||
ch_timeout <= ch_timeout - 1;
|
||||
ch_state <= '1';
|
||||
else
|
||||
ch_state <= '0';
|
||||
end if;
|
||||
if prev_change = '0' and disk_change = '1' then
|
||||
ch_timeout <= 15000000;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
c1541 : entity work.c1541_logic
|
||||
port map
|
||||
(
|
||||
clk_32M => clk32,
|
||||
reset => reset,
|
||||
|
||||
-- serial bus
|
||||
sb_data_oe => iec_data_o,
|
||||
sb_clk_oe => iec_clk_o,
|
||||
|
||||
sb_data_in => not iec_data_i,
|
||||
sb_clk_in => not iec_clk_i,
|
||||
sb_atn_in => not iec_atn_i,
|
||||
|
||||
c1541rom_clk => c1541rom_clk,
|
||||
c1541rom_addr => c1541rom_addr,
|
||||
c1541rom_data => c1541rom_data,
|
||||
c1541rom_wr => c1541rom_wr,
|
||||
|
||||
-- drive-side interface
|
||||
ds => drive_num, -- device select
|
||||
di => do, -- disk read data
|
||||
do => di, -- disk write data
|
||||
mode => mode, -- read/write
|
||||
stp => stp, -- stepper motor control
|
||||
mtr => mtr, -- motor on/off
|
||||
freq => open, -- motor frequency
|
||||
sync_n => sync_n, -- reading SYNC bytes
|
||||
byte_n => byte_n, -- byte ready
|
||||
wps_n => (not disk_readonly) xor ch_state, -- write-protect sense
|
||||
tr00_sense_n => tr00_sense_n, -- track 0 sense
|
||||
act => act -- activity LED
|
||||
);
|
||||
|
||||
floppy : entity work.gcr_floppy
|
||||
port map
|
||||
(
|
||||
clk32 => clk32,
|
||||
|
||||
dout => do, -- disk read data
|
||||
din => di,
|
||||
mode => mode,
|
||||
mtr => mtr, -- stepper motor on/off
|
||||
sync_n => sync_n, -- reading SYNC bytes
|
||||
byte_n => byte_n, -- byte ready
|
||||
|
||||
track => track,
|
||||
sector => sector,
|
||||
|
||||
byte_addr => byte_addr,
|
||||
ram_do => buff_dout,
|
||||
ram_di => buff_din,
|
||||
ram_we => buff_we,
|
||||
|
||||
ram_ready => not sd_busy
|
||||
);
|
||||
|
||||
track_buf : c1541_track
|
||||
port map
|
||||
(
|
||||
sd_lba => sd_lba,
|
||||
sd_rd => sd_rd,
|
||||
sd_wr => sd_wr,
|
||||
sd_ack => sd_ack,
|
||||
|
||||
sd_buff_addr => sd_buff_addr,
|
||||
sd_buff_dout => sd_buff_dout,
|
||||
sd_buff_din => sd_buff_din,
|
||||
sd_buff_wr => sd_buff_wr,
|
||||
|
||||
buff_addr => byte_addr,
|
||||
buff_dout => buff_dout,
|
||||
buff_din => buff_din,
|
||||
buff_we => buff_we,
|
||||
|
||||
save_track => save_track,
|
||||
change => disk_change,
|
||||
track => track,
|
||||
sector => sector,
|
||||
|
||||
clk => clk32,
|
||||
reset => reset,
|
||||
busy => sd_busy
|
||||
);
|
||||
|
||||
led <= act or sd_busy;
|
||||
|
||||
process (clk32)
|
||||
begin
|
||||
if rising_edge(clk32) then
|
||||
stp_r <= stp;
|
||||
act_r <= act;
|
||||
save_track <= '0';
|
||||
track <= track_num_dbl(6 downto 1);
|
||||
|
||||
if buff_we = '1' then track_modified <= '1'; end if;
|
||||
if disk_change = '1' then track_modified <= '0'; end if;
|
||||
|
||||
if reset = '1' then
|
||||
track_num_dbl <= "0100100";--"0000010";
|
||||
track_modified <= '0';
|
||||
else
|
||||
if mtr = '1' then
|
||||
if( (stp_r = "00" and stp = "10")
|
||||
or (stp_r = "10" and stp = "01")
|
||||
or (stp_r = "01" and stp = "11")
|
||||
or (stp_r = "11" and stp = "00")) then
|
||||
if track_num_dbl < "1010000" then
|
||||
track_num_dbl <= track_num_dbl + '1';
|
||||
end if;
|
||||
save_track <= track_modified;
|
||||
track_modified <= '0';
|
||||
end if;
|
||||
|
||||
if( (stp_r = "00" and stp = "11")
|
||||
or (stp_r = "10" and stp = "00")
|
||||
or (stp_r = "01" and stp = "10")
|
||||
or (stp_r = "11" and stp = "01")) then
|
||||
if track_num_dbl > "0000001" then
|
||||
track_num_dbl <= track_num_dbl - '1';
|
||||
end if;
|
||||
save_track <= track_modified;
|
||||
track_modified <= '0';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if act_r = '1' and act = '0' then -- stopping activity
|
||||
save_track <= track_modified;
|
||||
track_modified <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if; -- rising edge clock
|
||||
end process;
|
||||
|
||||
end struct;
|
||||
174
Commodore - 64_MiST/rtl/c1541/c1541_track.sv
Normal file
174
Commodore - 64_MiST/rtl/c1541/c1541_track.sv
Normal file
@@ -0,0 +1,174 @@
|
||||
//
|
||||
// c1541_track
|
||||
// Copyright (c) 2016 Sorgelig
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the Lesser GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module c1541_track
|
||||
(
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
output [31:0] sd_lba,
|
||||
output reg sd_rd,
|
||||
output reg sd_wr,
|
||||
input sd_ack,
|
||||
|
||||
input [8:0] sd_buff_addr,
|
||||
input [7:0] sd_buff_dout,
|
||||
output [7:0] sd_buff_din,
|
||||
input sd_buff_wr,
|
||||
|
||||
input save_track,
|
||||
input change,
|
||||
input [5:0] track,
|
||||
input [4:0] sector,
|
||||
input [7:0] buff_addr,
|
||||
output [7:0] buff_dout,
|
||||
input [7:0] buff_din,
|
||||
input buff_we,
|
||||
output reg busy
|
||||
);
|
||||
|
||||
assign sd_lba = lba;
|
||||
|
||||
trk_dpram buffer
|
||||
(
|
||||
.clock(clk),
|
||||
|
||||
.address_a(sd_buff_base + base_fix + sd_buff_addr),
|
||||
.data_a(sd_buff_dout),
|
||||
.wren_a(sd_ack & sd_buff_wr),
|
||||
.q_a(sd_buff_din),
|
||||
|
||||
.address_b({sector, buff_addr}),
|
||||
.data_b(buff_din),
|
||||
.wren_b(buff_we),
|
||||
.q_b(buff_dout)
|
||||
);
|
||||
|
||||
wire [9:0] start_sectors[41] =
|
||||
'{ 0, 0, 21, 42, 63, 84,105,126,147,168,189,210,231,252,273,294,315,336,357,376,395,
|
||||
414,433,452,471,490,508,526,544,562,580,598,615,632,649,666,683,700,717,734,751};
|
||||
|
||||
reg [31:0] lba;
|
||||
reg [12:0] base_fix;
|
||||
reg [12:0] sd_buff_base;
|
||||
|
||||
always @(posedge clk) begin
|
||||
reg old_ack;
|
||||
reg [5:0] cur_track = 0;
|
||||
reg old_change, ready = 0;
|
||||
reg saving = 0;
|
||||
|
||||
old_change <= change;
|
||||
if(~old_change & change) ready <= 1;
|
||||
|
||||
old_ack <= sd_ack;
|
||||
if(sd_ack) {sd_rd,sd_wr} <= 0;
|
||||
|
||||
if(reset) begin
|
||||
cur_track <= 'b111111;
|
||||
busy <= 0;
|
||||
sd_rd <= 0;
|
||||
sd_wr <= 0;
|
||||
saving<= 0;
|
||||
end
|
||||
else
|
||||
if(busy) begin
|
||||
if(old_ack && ~sd_ack) begin
|
||||
if(sd_buff_base < 'h1800) begin
|
||||
sd_buff_base <= sd_buff_base + 13'd512;
|
||||
lba <= lba + 1'd1;
|
||||
if(saving) sd_wr <= 1;
|
||||
else sd_rd <= 1;
|
||||
end
|
||||
else
|
||||
if(saving && (cur_track != track)) begin
|
||||
saving <= 0;
|
||||
cur_track <= track;
|
||||
sd_buff_base <= 0;
|
||||
base_fix <= start_sectors[track][0] ? 13'h1F00 : 13'h0000;
|
||||
lba <= start_sectors[track][9:1];
|
||||
sd_rd <= 1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
busy <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
if(ready) begin
|
||||
if(save_track && cur_track != 'b111111) begin
|
||||
saving <= 1;
|
||||
sd_buff_base <= 0;
|
||||
lba <= start_sectors[cur_track][9:1];
|
||||
sd_wr <= 1;
|
||||
busy <= 1;
|
||||
end
|
||||
else
|
||||
if((cur_track != track) || (old_change && ~change)) begin
|
||||
saving <= 0;
|
||||
cur_track <= track;
|
||||
sd_buff_base <= 0;
|
||||
base_fix <= start_sectors[track][0] ? 13'h1F00 : 13'h0000;
|
||||
lba <= start_sectors[track][9:1];
|
||||
sd_rd <= 1;
|
||||
busy <= 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module trk_dpram #(parameter DATAWIDTH=8, ADDRWIDTH=13)
|
||||
(
|
||||
input clock,
|
||||
|
||||
input [ADDRWIDTH-1:0] address_a,
|
||||
input [DATAWIDTH-1:0] data_a,
|
||||
input wren_a,
|
||||
output reg [DATAWIDTH-1:0] q_a,
|
||||
|
||||
input [ADDRWIDTH-1:0] address_b,
|
||||
input [DATAWIDTH-1:0] data_b,
|
||||
input wren_b,
|
||||
output reg [DATAWIDTH-1:0] q_b
|
||||
);
|
||||
|
||||
logic [DATAWIDTH-1:0] ram[0:(1<<ADDRWIDTH)-1];
|
||||
|
||||
always_ff@(posedge clock) begin
|
||||
if(wren_a) begin
|
||||
ram[address_a] <= data_a;
|
||||
q_a <= data_a;
|
||||
end else begin
|
||||
q_a <= ram[address_a];
|
||||
end
|
||||
end
|
||||
|
||||
always_ff@(posedge clock) begin
|
||||
if(wren_b) begin
|
||||
ram[address_b] <= data_b;
|
||||
q_b <= data_b;
|
||||
end else begin
|
||||
q_b <= ram[address_b];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
675
Commodore - 64_MiST/rtl/c1541/c1541_via6522.vhd
Normal file
675
Commodore - 64_MiST/rtl/c1541/c1541_via6522.vhd
Normal file
@@ -0,0 +1,675 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- (C) COPYRIGHT 2007-2017, Gideon's Logic Architectures
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- Title : VIA 6522
|
||||
-------------------------------------------------------------------------------
|
||||
-- Author : Gideon Zweijtzer <gideon.zweijtzer@gmail.com>
|
||||
-------------------------------------------------------------------------------
|
||||
-- Description: This module implements the 6522 VIA chip.
|
||||
-- Please note: A LOT OF REVERSE ENGINEERING has been done to
|
||||
-- make this module as accurate as it is now. Please do not copy
|
||||
-- (use in your own projects) without written permission of the
|
||||
-- author.
|
||||
-------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity c1541_via6522 is
|
||||
port (
|
||||
clock : in std_logic;
|
||||
rising : in std_logic;
|
||||
falling : in std_logic;
|
||||
reset : in std_logic;
|
||||
|
||||
addr : in std_logic_vector(3 downto 0);
|
||||
wen : in std_logic;
|
||||
ren : in std_logic;
|
||||
data_in : in std_logic_vector(7 downto 0);
|
||||
data_out : out std_logic_vector(7 downto 0);
|
||||
|
||||
phi2_ref : out std_logic;
|
||||
|
||||
-- pio --
|
||||
port_a_o : out std_logic_vector(7 downto 0);
|
||||
port_a_t_l : out std_logic_vector(7 downto 0);
|
||||
port_a_i : in std_logic_vector(7 downto 0);
|
||||
|
||||
port_b_o : out std_logic_vector(7 downto 0);
|
||||
port_b_t_l : out std_logic_vector(7 downto 0);
|
||||
port_b_i : in std_logic_vector(7 downto 0);
|
||||
|
||||
-- handshake pins
|
||||
ca1_i : in std_logic;
|
||||
|
||||
ca2_o : out std_logic;
|
||||
ca2_i : in std_logic;
|
||||
ca2_t_l : out std_logic;
|
||||
|
||||
cb1_o : out std_logic;
|
||||
cb1_i : in std_logic;
|
||||
cb1_t_l : out std_logic;
|
||||
|
||||
cb2_o : out std_logic;
|
||||
cb2_i : in std_logic;
|
||||
cb2_t_l : out std_logic;
|
||||
|
||||
irq_l : out std_logic );
|
||||
|
||||
end c1541_via6522;
|
||||
|
||||
architecture Gideon of c1541_via6522 is
|
||||
|
||||
type pio_t is
|
||||
record
|
||||
pra : std_logic_vector(7 downto 0);
|
||||
ddra : std_logic_vector(7 downto 0);
|
||||
prb : std_logic_vector(7 downto 0);
|
||||
ddrb : std_logic_vector(7 downto 0);
|
||||
end record;
|
||||
|
||||
constant pio_default : pio_t := (others => (others => '0'));
|
||||
constant latch_reset_pattern : std_logic_vector(15 downto 0) := X"5550";
|
||||
|
||||
signal pio_i : pio_t;
|
||||
signal port_a_c : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal port_b_c : std_logic_vector(7 downto 0) := (others => '0');
|
||||
|
||||
signal irq_mask : std_logic_vector(6 downto 0) := (others => '0');
|
||||
signal irq_flags : std_logic_vector(6 downto 0) := (others => '0');
|
||||
signal irq_events : std_logic_vector(6 downto 0) := (others => '0');
|
||||
signal irq_out : std_logic;
|
||||
|
||||
signal timer_a_latch : std_logic_vector(15 downto 0) := latch_reset_pattern;
|
||||
signal timer_b_latch : std_logic_vector(15 downto 0) := latch_reset_pattern;
|
||||
signal timer_a_count : std_logic_vector(15 downto 0) := latch_reset_pattern;
|
||||
signal timer_b_count : std_logic_vector(15 downto 0) := latch_reset_pattern;
|
||||
signal timer_a_out : std_logic;
|
||||
signal timer_b_tick : std_logic;
|
||||
|
||||
signal acr, pcr : std_logic_vector(7 downto 0) := X"00";
|
||||
signal shift_reg : std_logic_vector(7 downto 0) := X"00";
|
||||
signal serport_en : std_logic;
|
||||
signal ser_cb2_o : std_logic;
|
||||
signal hs_cb2_o : std_logic;
|
||||
signal trigger_serial: std_logic;
|
||||
|
||||
alias ca2_event : std_logic is irq_events(0);
|
||||
alias ca1_event : std_logic is irq_events(1);
|
||||
alias serial_event : std_logic is irq_events(2);
|
||||
alias cb2_event : std_logic is irq_events(3);
|
||||
alias cb1_event : std_logic is irq_events(4);
|
||||
alias timer_b_event : std_logic is irq_events(5);
|
||||
alias timer_a_event : std_logic is irq_events(6);
|
||||
|
||||
alias ca2_flag : std_logic is irq_flags(0);
|
||||
alias ca1_flag : std_logic is irq_flags(1);
|
||||
alias serial_flag : std_logic is irq_flags(2);
|
||||
alias cb2_flag : std_logic is irq_flags(3);
|
||||
alias cb1_flag : std_logic is irq_flags(4);
|
||||
alias timer_b_flag : std_logic is irq_flags(5);
|
||||
alias timer_a_flag : std_logic is irq_flags(6);
|
||||
|
||||
alias tmr_a_output_en : std_logic is acr(7);
|
||||
alias tmr_a_freerun : std_logic is acr(6);
|
||||
alias tmr_b_count_mode : std_logic is acr(5);
|
||||
alias shift_dir : std_logic is acr(4);
|
||||
alias shift_clk_sel : std_logic_vector(1 downto 0) is acr(3 downto 2);
|
||||
alias shift_mode_control : std_logic_vector(2 downto 0) is acr(4 downto 2);
|
||||
alias pb_latch_en : std_logic is acr(1);
|
||||
alias pa_latch_en : std_logic is acr(0);
|
||||
|
||||
alias cb2_is_output : std_logic is pcr(7);
|
||||
alias cb2_edge_select : std_logic is pcr(6); -- for when CB2 is input
|
||||
alias cb2_no_irq_clr : std_logic is pcr(5); -- for when CB2 is input
|
||||
alias cb2_out_mode : std_logic_vector(1 downto 0) is pcr(6 downto 5);
|
||||
alias cb1_edge_select : std_logic is pcr(4);
|
||||
|
||||
alias ca2_is_output : std_logic is pcr(3);
|
||||
alias ca2_edge_select : std_logic is pcr(2); -- for when CA2 is input
|
||||
alias ca2_no_irq_clr : std_logic is pcr(1); -- for when CA2 is input
|
||||
alias ca2_out_mode : std_logic_vector(1 downto 0) is pcr(2 downto 1);
|
||||
alias ca1_edge_select : std_logic is pcr(0);
|
||||
|
||||
signal ira, irb : std_logic_vector(7 downto 0) := (others => '0');
|
||||
|
||||
signal write_t1c_h : std_logic;
|
||||
signal write_t2c_h : std_logic;
|
||||
|
||||
signal ca1_c, ca2_c : std_logic;
|
||||
signal cb1_c, cb2_c : std_logic;
|
||||
signal ca1_d, ca2_d : std_logic;
|
||||
signal cb1_d, cb2_d : std_logic;
|
||||
|
||||
signal ca2_handshake_o : std_logic;
|
||||
signal ca2_pulse_o : std_logic;
|
||||
signal cb2_handshake_o : std_logic;
|
||||
signal cb2_pulse_o : std_logic;
|
||||
signal shift_active : std_logic;
|
||||
begin
|
||||
irq_l <= not irq_out;
|
||||
|
||||
write_t1c_h <= '1' when addr = X"5" and wen='1' and falling = '1' else '0';
|
||||
write_t2c_h <= '1' when addr = X"9" and wen='1' and falling = '1' else '0';
|
||||
|
||||
ca1_event <= (ca1_c xor ca1_d) and (ca1_d xor ca1_edge_select);
|
||||
ca2_event <= (ca2_c xor ca2_d) and (ca2_d xor ca2_edge_select);
|
||||
cb1_event <= (cb1_c xor cb1_d) and (cb1_d xor cb1_edge_select);
|
||||
cb2_event <= (cb2_c xor cb2_d) and (cb2_d xor cb2_edge_select);
|
||||
|
||||
ca2_t_l <= not ca2_is_output;
|
||||
cb2_t_l <= not cb2_is_output when serport_en='0' else shift_dir;
|
||||
cb2_o <= hs_cb2_o when serport_en='0' else ser_cb2_o;
|
||||
|
||||
with ca2_out_mode select ca2_o <=
|
||||
ca2_handshake_o when "00",
|
||||
ca2_pulse_o when "01",
|
||||
'0' when "10",
|
||||
'1' when others;
|
||||
|
||||
with cb2_out_mode select hs_cb2_o <=
|
||||
cb2_handshake_o when "00",
|
||||
cb2_pulse_o when "01",
|
||||
'0' when "10",
|
||||
'1' when others;
|
||||
|
||||
process(irq_flags, irq_mask)
|
||||
begin
|
||||
if (irq_flags and irq_mask) = "0000000" then
|
||||
irq_out <= '0';
|
||||
else
|
||||
irq_out <= '1';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process(clock)
|
||||
begin
|
||||
if rising_edge(clock) then
|
||||
if rising = '1' then
|
||||
phi2_ref <= '1';
|
||||
elsif falling = '1' then
|
||||
phi2_ref <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
process(clock)
|
||||
begin
|
||||
if rising_edge(clock) then
|
||||
-- CA1/CA2/CB1/CB2 edge detect flipflops
|
||||
ca1_c <= To_X01(ca1_i);
|
||||
ca2_c <= To_X01(ca2_i);
|
||||
cb1_c <= To_X01(cb1_i);
|
||||
cb2_c <= To_X01(cb2_i);
|
||||
|
||||
ca1_d <= ca1_c;
|
||||
ca2_d <= ca2_c;
|
||||
cb1_d <= cb1_c;
|
||||
cb2_d <= cb2_c;
|
||||
|
||||
-- input registers
|
||||
port_a_c <= port_a_i;
|
||||
port_b_c <= port_b_i;
|
||||
|
||||
-- input latch emulation
|
||||
if pa_latch_en = '0' or ca1_event = '1' then
|
||||
ira <= port_a_c;
|
||||
end if;
|
||||
|
||||
if pb_latch_en = '0' or cb1_event = '1' then
|
||||
irb <= port_b_c;
|
||||
end if;
|
||||
|
||||
-- CA2 logic
|
||||
if ca1_event = '1' then
|
||||
ca2_handshake_o <= '1';
|
||||
elsif (ren = '1' or wen = '1') and addr = X"1" and falling = '1' then
|
||||
ca2_handshake_o <= '0';
|
||||
end if;
|
||||
|
||||
if falling = '1' then
|
||||
if (ren = '1' or wen = '1') and addr = X"1" then
|
||||
ca2_pulse_o <= '0';
|
||||
else
|
||||
ca2_pulse_o <= '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- CB2 logic
|
||||
if cb1_event = '1' then
|
||||
cb2_handshake_o <= '1';
|
||||
elsif (ren = '1' or wen = '1') and addr = X"0" and falling = '1' then
|
||||
cb2_handshake_o <= '0';
|
||||
end if;
|
||||
|
||||
if falling = '1' then
|
||||
if (ren = '1' or wen = '1') and addr = X"0" then
|
||||
cb2_pulse_o <= '0';
|
||||
else
|
||||
cb2_pulse_o <= '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Interrupt logic
|
||||
irq_flags <= irq_flags or irq_events;
|
||||
|
||||
if falling = '1' then
|
||||
trigger_serial <= '0';
|
||||
end if;
|
||||
|
||||
-- Writes --
|
||||
if wen='1' and falling = '1' then
|
||||
case addr is
|
||||
when X"0" => -- ORB
|
||||
pio_i.prb <= data_in;
|
||||
if cb2_no_irq_clr='0' then
|
||||
cb2_flag <= '0';
|
||||
end if;
|
||||
cb1_flag <= '0';
|
||||
|
||||
when X"1" => -- ORA
|
||||
pio_i.pra <= data_in;
|
||||
if ca2_no_irq_clr='0' then
|
||||
ca2_flag <= '0';
|
||||
end if;
|
||||
ca1_flag <= '0';
|
||||
|
||||
when X"2" => -- DDRB
|
||||
pio_i.ddrb <= data_in;
|
||||
|
||||
when X"3" => -- DDRA
|
||||
pio_i.ddra <= data_in;
|
||||
|
||||
when X"4" => -- TA LO counter (write=latch)
|
||||
timer_a_latch(7 downto 0) <= data_in;
|
||||
|
||||
when X"5" => -- TA HI counter
|
||||
timer_a_latch(15 downto 8) <= data_in;
|
||||
timer_a_flag <= '0';
|
||||
|
||||
when X"6" => -- TA LO latch
|
||||
timer_a_latch(7 downto 0) <= data_in;
|
||||
|
||||
when X"7" => -- TA HI latch
|
||||
timer_a_latch(15 downto 8) <= data_in;
|
||||
timer_a_flag <= '0';
|
||||
|
||||
when X"8" => -- TB LO latch
|
||||
timer_b_latch(7 downto 0) <= data_in;
|
||||
|
||||
when X"9" => -- TB HI counter
|
||||
timer_b_flag <= '0';
|
||||
|
||||
when X"A" => -- Serial port
|
||||
serial_flag <= '0';
|
||||
if shift_active = '0' then
|
||||
trigger_serial <= '1';
|
||||
end if;
|
||||
|
||||
when X"B" => -- ACR (Auxiliary Control Register)
|
||||
acr <= data_in;
|
||||
|
||||
when X"C" => -- PCR (Peripheral Control Register)
|
||||
pcr <= data_in;
|
||||
|
||||
when X"D" => -- IFR
|
||||
irq_flags <= irq_flags and not data_in(6 downto 0);
|
||||
|
||||
when X"E" => -- IER
|
||||
if data_in(7)='1' then -- set
|
||||
irq_mask <= irq_mask or data_in(6 downto 0);
|
||||
else -- clear
|
||||
irq_mask <= irq_mask and not data_in(6 downto 0);
|
||||
end if;
|
||||
|
||||
when X"F" => -- ORA no handshake
|
||||
pio_i.pra <= data_in;
|
||||
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
end if;
|
||||
|
||||
-- Reads - Output only --
|
||||
data_out <= X"00";
|
||||
case addr is
|
||||
when X"0" => -- ORB
|
||||
--Port B reads its own output register for pins set to output.
|
||||
data_out <= (pio_i.prb and pio_i.ddrb) or (irb and not pio_i.ddrb);
|
||||
when X"1" => -- ORA
|
||||
data_out <= ira;
|
||||
when X"2" => -- DDRB
|
||||
data_out <= pio_i.ddrb;
|
||||
when X"3" => -- DDRA
|
||||
data_out <= pio_i.ddra;
|
||||
when X"4" => -- TA LO counter
|
||||
data_out <= timer_a_count(7 downto 0);
|
||||
when X"5" => -- TA HI counter
|
||||
data_out <= timer_a_count(15 downto 8);
|
||||
when X"6" => -- TA LO latch
|
||||
data_out <= timer_a_latch(7 downto 0);
|
||||
when X"7" => -- TA HI latch
|
||||
data_out <= timer_a_latch(15 downto 8);
|
||||
when X"8" => -- TA LO counter
|
||||
data_out <= timer_b_count(7 downto 0);
|
||||
when X"9" => -- TA HI counter
|
||||
data_out <= timer_b_count(15 downto 8);
|
||||
when X"A" => -- SR
|
||||
data_out <= shift_reg;
|
||||
when X"B" => -- ACR
|
||||
data_out <= acr;
|
||||
when X"C" => -- PCR
|
||||
data_out <= pcr;
|
||||
when X"D" => -- IFR
|
||||
data_out <= irq_out & irq_flags;
|
||||
when X"E" => -- IER
|
||||
data_out <= '0' & irq_mask;
|
||||
when X"F" => -- ORA
|
||||
data_out <= ira;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
|
||||
-- Read actions --
|
||||
if ren = '1' and falling = '1' then
|
||||
case addr is
|
||||
when X"0" => -- ORB
|
||||
if cb2_no_irq_clr='0' then
|
||||
cb2_flag <= '0';
|
||||
end if;
|
||||
cb1_flag <= '0';
|
||||
|
||||
when X"1" => -- ORA
|
||||
if ca2_no_irq_clr='0' then
|
||||
ca2_flag <= '0';
|
||||
end if;
|
||||
ca1_flag <= '0';
|
||||
|
||||
when X"4" => -- TA LO counter
|
||||
timer_a_flag <= '0';
|
||||
|
||||
when X"8" => -- TB LO counter
|
||||
timer_b_flag <= '0';
|
||||
|
||||
when X"A" => -- SR
|
||||
serial_flag <= '0';
|
||||
trigger_serial <= '1';
|
||||
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if reset='1' then
|
||||
pio_i <= pio_default;
|
||||
irq_mask <= (others => '0');
|
||||
irq_flags <= (others => '0');
|
||||
acr <= (others => '0');
|
||||
pcr <= (others => '0');
|
||||
ca2_handshake_o <= '1';
|
||||
ca2_pulse_o <= '1';
|
||||
cb2_handshake_o <= '1';
|
||||
cb2_pulse_o <= '1';
|
||||
timer_a_latch <= latch_reset_pattern;
|
||||
timer_b_latch <= latch_reset_pattern;
|
||||
trigger_serial <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- PIO Out select --
|
||||
port_a_o <= pio_i.pra;
|
||||
port_b_o(6 downto 0) <= pio_i.prb(6 downto 0);
|
||||
port_b_o(7) <= pio_i.prb(7) when tmr_a_output_en='0' else timer_a_out;
|
||||
|
||||
port_a_t_l <= not pio_i.ddra;
|
||||
port_b_t_l(6 downto 0) <= not pio_i.ddrb(6 downto 0);
|
||||
port_b_t_l(7) <= not (pio_i.ddrb(7) or tmr_a_output_en);
|
||||
|
||||
|
||||
-- Timer A
|
||||
tmr_a: block
|
||||
signal timer_a_reload : std_logic;
|
||||
signal timer_a_oneshot_trig : std_logic;
|
||||
signal timer_a_toggle : std_logic;
|
||||
begin
|
||||
process(clock)
|
||||
begin
|
||||
if rising_edge(clock) then
|
||||
if falling = '1' then
|
||||
-- always count, or load
|
||||
|
||||
if timer_a_reload = '1' then
|
||||
timer_a_count <= timer_a_latch;
|
||||
timer_a_reload <= '0';
|
||||
timer_a_oneshot_trig <= '0';
|
||||
else
|
||||
if timer_a_count = X"0000" then
|
||||
-- generate an event if we were triggered
|
||||
timer_a_reload <= '1';
|
||||
end if;
|
||||
--Timer coutinues to count in both free run and one shot.
|
||||
timer_a_count <= timer_a_count - X"0001";
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if rising = '1' then
|
||||
if timer_a_event = '1' then
|
||||
timer_a_toggle <= not timer_a_toggle;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if write_t1c_h = '1' then
|
||||
timer_a_toggle <= '0';
|
||||
timer_a_count <= data_in & timer_a_latch(7 downto 0);
|
||||
timer_a_reload <= '0';
|
||||
timer_a_oneshot_trig <= '1';
|
||||
end if;
|
||||
|
||||
if reset='1' then
|
||||
timer_a_toggle <= '1';
|
||||
timer_a_count <= latch_reset_pattern;
|
||||
timer_a_reload <= '0';
|
||||
timer_a_oneshot_trig <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
timer_a_out <= timer_a_toggle;
|
||||
timer_a_event <= rising and timer_a_reload and (tmr_a_freerun or timer_a_oneshot_trig);
|
||||
|
||||
end block tmr_a;
|
||||
|
||||
-- Timer B
|
||||
tmr_b: block
|
||||
signal timer_b_reload_lo : std_logic;
|
||||
signal timer_b_oneshot_trig : std_logic;
|
||||
signal timer_b_timeout : std_logic;
|
||||
signal pb6_c, pb6_d : std_logic;
|
||||
begin
|
||||
process(clock)
|
||||
variable timer_b_decrement : std_logic;
|
||||
begin
|
||||
if rising_edge(clock) then
|
||||
timer_b_decrement := '0';
|
||||
|
||||
if rising = '1' then
|
||||
pb6_c <= To_X01(port_b_i(6));
|
||||
pb6_d <= pb6_c;
|
||||
end if;
|
||||
|
||||
if falling = '1' then
|
||||
timer_b_timeout <= '0';
|
||||
timer_b_tick <= '0';
|
||||
|
||||
if tmr_b_count_mode = '1' then
|
||||
if (pb6_d='1' and pb6_c='0') then
|
||||
timer_b_decrement := '1';
|
||||
end if;
|
||||
else -- one shot or used for shift register
|
||||
timer_b_decrement := '1';
|
||||
end if;
|
||||
|
||||
if timer_b_decrement = '1' then
|
||||
if timer_b_count = X"0000" then
|
||||
if timer_b_oneshot_trig = '1' then
|
||||
timer_b_oneshot_trig <= '0';
|
||||
timer_b_timeout <= '1';
|
||||
end if;
|
||||
end if;
|
||||
if timer_b_count(7 downto 0) = X"00" then
|
||||
case shift_mode_control is
|
||||
when "001" | "101" | "100" =>
|
||||
timer_b_reload_lo <= '1';
|
||||
timer_b_tick <= '1';
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
end if;
|
||||
timer_b_count <= timer_b_count - X"0001";
|
||||
end if;
|
||||
if timer_b_reload_lo = '1' then
|
||||
timer_b_count(7 downto 0) <= timer_b_latch(7 downto 0);
|
||||
timer_b_reload_lo <= '0';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if write_t2c_h = '1' then
|
||||
timer_b_count <= data_in & timer_b_latch(7 downto 0);
|
||||
timer_b_oneshot_trig <= '1';
|
||||
end if;
|
||||
|
||||
if reset='1' then
|
||||
timer_b_count <= latch_reset_pattern;
|
||||
timer_b_reload_lo <= '0';
|
||||
timer_b_oneshot_trig <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
timer_b_event <= rising and timer_b_timeout;
|
||||
|
||||
end block tmr_b;
|
||||
|
||||
ser: block
|
||||
signal shift_clock_d : std_logic;
|
||||
signal shift_clock : std_logic;
|
||||
signal shift_tick_r : std_logic;
|
||||
signal shift_tick_f : std_logic;
|
||||
signal cb2_c : std_logic := '0';
|
||||
signal bit_cnt : integer range 0 to 7;
|
||||
signal shift_pulse : std_logic;
|
||||
begin
|
||||
process(shift_active, timer_b_tick, shift_clk_sel, shift_clock, shift_clock_d)
|
||||
begin
|
||||
case shift_clk_sel is
|
||||
when "10" =>
|
||||
shift_pulse <= '1';
|
||||
|
||||
when "00"|"01" =>
|
||||
shift_pulse <= timer_b_tick;
|
||||
|
||||
when others =>
|
||||
shift_pulse <= shift_clock and not shift_clock_d;
|
||||
|
||||
end case;
|
||||
|
||||
if shift_active = '0' then
|
||||
shift_pulse <= '0';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process(clock)
|
||||
begin
|
||||
if rising_edge(clock) then
|
||||
if rising = '1' then
|
||||
cb2_c <= To_X01(cb2_i);
|
||||
|
||||
if shift_active='0' then
|
||||
shift_clock <= '1';
|
||||
elsif shift_clk_sel = "11" then
|
||||
shift_clock <= To_X01(cb1_i);
|
||||
elsif shift_pulse = '1' then
|
||||
shift_clock <= not shift_clock;
|
||||
end if;
|
||||
|
||||
shift_clock_d <= shift_clock;
|
||||
|
||||
if shift_tick_f = '1' then
|
||||
ser_cb2_o <= shift_reg(7);
|
||||
end if;
|
||||
end if;
|
||||
if reset = '1' then
|
||||
shift_clock <= '1';
|
||||
shift_clock_d <= '1';
|
||||
ser_cb2_o <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cb1_t_l <= '1' when shift_clk_sel="11" else not serport_en;
|
||||
cb1_o <= shift_clock_d;
|
||||
|
||||
serport_en <= shift_dir or shift_clk_sel(1) or shift_clk_sel(0);
|
||||
|
||||
process(clock)
|
||||
begin
|
||||
if rising_edge(clock) then
|
||||
if reset = '1' then
|
||||
shift_reg <= X"FF";
|
||||
shift_tick_r <= '0';
|
||||
shift_tick_f <= '0';
|
||||
elsif falling = '1' then
|
||||
shift_tick_r <= not shift_clock_d and shift_clock;
|
||||
shift_tick_f <= shift_clock_d and not shift_clock;
|
||||
|
||||
if wen = '1' and addr = X"A" then
|
||||
shift_reg <= data_in;
|
||||
elsif shift_tick_r = '1' then
|
||||
if shift_dir='1' then -- output
|
||||
shift_reg <= shift_reg(6 downto 0) & shift_reg(7);
|
||||
else
|
||||
shift_reg <= shift_reg(6 downto 0) & cb2_c;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- tell people that we're ready!
|
||||
serial_event <= shift_tick_r and not shift_active and rising;
|
||||
|
||||
process(clock)
|
||||
begin
|
||||
if rising_edge(clock) then
|
||||
if falling = '1' then
|
||||
if shift_active = '0' then
|
||||
if trigger_serial = '1' then
|
||||
bit_cnt <= 7;
|
||||
shift_active <= '1';
|
||||
end if;
|
||||
else -- we're active
|
||||
if shift_clk_sel = "00" then
|
||||
shift_active <= shift_dir; -- when '1' we're active, but for mode 000 we go inactive.
|
||||
elsif shift_pulse = '1' and shift_clock = '1' then
|
||||
if bit_cnt = 0 then
|
||||
shift_active <= '0';
|
||||
else
|
||||
bit_cnt <= bit_cnt - 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if reset='1' then
|
||||
shift_active <= '0';
|
||||
bit_cnt <= 0;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
end block ser;
|
||||
end Gideon;
|
||||
137
Commodore - 64_MiST/rtl/c1541/cpu/alu.vhd
Normal file
137
Commodore - 64_MiST/rtl/c1541/cpu/alu.vhd
Normal file
@@ -0,0 +1,137 @@
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity alu is
|
||||
generic (
|
||||
support_bcd : boolean := true );
|
||||
port (
|
||||
operation : in std_logic_vector(2 downto 0);
|
||||
enable : in std_logic;
|
||||
|
||||
n_in : in std_logic;
|
||||
v_in : in std_logic;
|
||||
z_in : in std_logic;
|
||||
c_in : in std_logic;
|
||||
d_in : in std_logic;
|
||||
|
||||
data_a : in std_logic_vector(7 downto 0);
|
||||
data_b : in std_logic_vector(7 downto 0);
|
||||
|
||||
n_out : out std_logic;
|
||||
v_out : out std_logic;
|
||||
z_out : out std_logic;
|
||||
c_out : out std_logic;
|
||||
|
||||
data_out : out std_logic_vector(7 downto 0));
|
||||
|
||||
end alu;
|
||||
|
||||
architecture gideon of alu is
|
||||
signal data_out_i : std_logic_vector(7 downto 0) := X"FF";
|
||||
signal zero : std_logic;
|
||||
signal sum_c : std_logic;
|
||||
signal sum_n : std_logic;
|
||||
signal sum_z : std_logic;
|
||||
signal sum_v : std_logic;
|
||||
signal sum_result : std_logic_vector(7 downto 0) := X"FF";
|
||||
signal oper4 : std_logic_vector(3 downto 0);
|
||||
begin
|
||||
|
||||
-- ORA $nn AND $nn EOR $nn ADC $nn STA $nn LDA $nn CMP $nn SBC $nn
|
||||
|
||||
with oper4 select data_out_i <=
|
||||
data_a or data_b when "1000",
|
||||
data_a and data_b when "1001",
|
||||
data_a xor data_b when "1010",
|
||||
sum_result when "1011" | "1110" | "1111",
|
||||
data_b when others;
|
||||
|
||||
zero <= '1' when data_out_i = X"00" else '0';
|
||||
|
||||
sum: process(data_a, data_b, c_in, operation, d_in)
|
||||
variable b : std_logic_vector(7 downto 0);
|
||||
variable sum_l : std_logic_vector(4 downto 0);
|
||||
variable sum_h : std_logic_vector(4 downto 0);
|
||||
begin
|
||||
-- for subtraction invert second operand
|
||||
if operation(2)='1' then -- invert b
|
||||
b := not data_b;
|
||||
else
|
||||
b := data_b;
|
||||
end if;
|
||||
|
||||
-- sum_l(4) = carry of lower end, carry in is masked to '1' for CMP
|
||||
sum_l := ('0' & data_a(3 downto 0)) + ('0' & b(3 downto 0)) + (c_in or not operation(0));
|
||||
sum_h := ('0' & data_a(7 downto 4)) + ('0' & b(7 downto 4)) + sum_l(4);
|
||||
|
||||
if sum_l(3 downto 0)="0000" and sum_h(3 downto 0)="0000" then
|
||||
sum_z <= '1';
|
||||
else
|
||||
sum_z <= '0';
|
||||
end if;
|
||||
|
||||
sum_n <= sum_h(3);
|
||||
sum_c <= sum_h(4);
|
||||
sum_v <= (sum_h(3) xor data_a(7)) and (sum_h(3) xor data_b(7) xor operation(2));
|
||||
|
||||
-- fix up in decimal mode (not for CMP!)
|
||||
if d_in='1' and support_bcd then
|
||||
if operation(2)='0' then -- ADC
|
||||
sum_h := ('0' & data_a(7 downto 4)) + ('0' & b(7 downto 4));
|
||||
|
||||
if sum_l(4) = '1' or sum_l(3 downto 2)="11" or sum_l(3 downto 1)="101" then -- >9 (10-11, 12-15)
|
||||
sum_l := sum_l + ('0' & X"6");
|
||||
sum_l(4) := '1';
|
||||
end if;
|
||||
|
||||
-- negative when sum_h + sum_l(4) = 8
|
||||
sum_h := sum_h + sum_l(4);
|
||||
sum_n <= sum_h(3);
|
||||
|
||||
if sum_h(4) = '1' or sum_h(3 downto 2)="11" or sum_h(3 downto 1)="101" then --
|
||||
sum_h := sum_h + 6;
|
||||
sum_c <= '1';
|
||||
end if;
|
||||
|
||||
-- carry and overflow are output after fix
|
||||
-- sum_c <= sum_h(4);
|
||||
-- sum_v <= (sum_h(3) xor data_a(7)) and (sum_h(3) xor data_b(7) xor operation(2));
|
||||
|
||||
elsif operation(0)='1' then -- SBC
|
||||
-- flags are not adjusted in subtract mode
|
||||
if sum_l(4) = '0' then
|
||||
sum_l := sum_l - 6;
|
||||
end if;
|
||||
if sum_h(4) = '0' then
|
||||
sum_h := sum_h - 6;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
sum_result <= sum_h(3 downto 0) & sum_l(3 downto 0);
|
||||
end process;
|
||||
|
||||
oper4 <= enable & operation;
|
||||
|
||||
with oper4 select c_out <=
|
||||
sum_c when "1011" | "1111" | "1110",
|
||||
c_in when others;
|
||||
|
||||
with oper4 select z_out <=
|
||||
sum_z when "1011" | "1111" | "1110",
|
||||
zero when "1000" | "1001" | "1010" | "1101",
|
||||
z_in when others;
|
||||
|
||||
with oper4 select n_out <=
|
||||
sum_n when "1011" | "1111",
|
||||
data_out_i(7) when "1000" | "1001" | "1010" | "1101" | "1110",
|
||||
n_in when others;
|
||||
|
||||
with oper4 select v_out <=
|
||||
sum_v when "1011" | "1111",
|
||||
v_in when others;
|
||||
|
||||
data_out <= data_out_i;
|
||||
end gideon;
|
||||
66
Commodore - 64_MiST/rtl/c1541/cpu/bit_cpx_cpy.vhd
Normal file
66
Commodore - 64_MiST/rtl/c1541/cpu/bit_cpx_cpy.vhd
Normal file
@@ -0,0 +1,66 @@
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity bit_cpx_cpy is
|
||||
port (
|
||||
operation : in std_logic_vector(2 downto 0);
|
||||
enable : in std_logic := '1'; -- instruction(1 downto 0)="00"
|
||||
|
||||
n_in : in std_logic;
|
||||
v_in : in std_logic;
|
||||
z_in : in std_logic;
|
||||
c_in : in std_logic;
|
||||
|
||||
data_in : in std_logic_vector(7 downto 0);
|
||||
a_reg : in std_logic_vector(7 downto 0);
|
||||
x_reg : in std_logic_vector(7 downto 0);
|
||||
y_reg : in std_logic_vector(7 downto 0);
|
||||
|
||||
n_out : out std_logic;
|
||||
v_out : out std_logic;
|
||||
z_out : out std_logic;
|
||||
c_out : out std_logic );
|
||||
|
||||
end bit_cpx_cpy;
|
||||
|
||||
architecture gideon of bit_cpx_cpy is
|
||||
signal reg : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal diff : std_logic_vector(8 downto 0) := (others => '0');
|
||||
signal zero_cmp : std_logic;
|
||||
signal zero_ld : std_logic;
|
||||
signal zero_bit : std_logic;
|
||||
|
||||
signal oper4 : std_logic_vector(3 downto 0);
|
||||
begin
|
||||
-- *** BIT *** *** STY LDY CPY CPX
|
||||
reg <= x_reg when operation(0)='1' else y_reg;
|
||||
|
||||
diff <= ('1' & reg) - ('0' & data_in);
|
||||
zero_cmp <= '1' when diff(7 downto 0)=X"00" else '0';
|
||||
zero_ld <= '1' when data_in=X"00" else '0';
|
||||
zero_bit <= '1' when (data_in and a_reg)=X"00" else '0';
|
||||
|
||||
oper4 <= enable & operation;
|
||||
|
||||
with oper4 select c_out <=
|
||||
diff(8) when "1110" | "1111", -- CPX / CPY
|
||||
c_in when others;
|
||||
|
||||
with oper4 select z_out <=
|
||||
zero_cmp when "1110" | "1111", -- CPX / CPY
|
||||
zero_ld when "1101",
|
||||
zero_bit when "1001",
|
||||
z_in when others;
|
||||
|
||||
with oper4 select n_out <=
|
||||
diff(7) when "1110" | "1111", -- CPX / CPY
|
||||
data_in(7) when "1101" | "1001", -- LDY / BIT
|
||||
n_in when others;
|
||||
|
||||
with oper4 select v_out <=
|
||||
data_in(6) when "1001", -- BIT
|
||||
v_in when others;
|
||||
|
||||
end gideon;
|
||||
193
Commodore - 64_MiST/rtl/c1541/cpu/data_oper.vhd
Normal file
193
Commodore - 64_MiST/rtl/c1541/cpu/data_oper.vhd
Normal file
@@ -0,0 +1,193 @@
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
library work;
|
||||
use work.pkg_6502_decode.all;
|
||||
|
||||
-- this module puts the alu, shifter and bit/compare unit together
|
||||
|
||||
entity data_oper is
|
||||
generic (
|
||||
support_bcd : boolean := true );
|
||||
port (
|
||||
inst : in std_logic_vector(7 downto 0);
|
||||
|
||||
n_in : in std_logic;
|
||||
v_in : in std_logic;
|
||||
z_in : in std_logic;
|
||||
c_in : in std_logic;
|
||||
d_in : in std_logic;
|
||||
i_in : in std_logic;
|
||||
|
||||
data_in : in std_logic_vector(7 downto 0);
|
||||
a_reg : in std_logic_vector(7 downto 0);
|
||||
x_reg : in std_logic_vector(7 downto 0);
|
||||
y_reg : in std_logic_vector(7 downto 0);
|
||||
s_reg : in std_logic_vector(7 downto 0);
|
||||
|
||||
alu_out : out std_logic_vector(7 downto 0);
|
||||
mem_out : out std_logic_vector(7 downto 0);
|
||||
impl_out : out std_logic_vector(7 downto 0);
|
||||
|
||||
set_a : out std_logic;
|
||||
set_x : out std_logic;
|
||||
set_y : out std_logic;
|
||||
set_s : out std_logic;
|
||||
|
||||
n_out : out std_logic;
|
||||
v_out : out std_logic;
|
||||
z_out : out std_logic;
|
||||
c_out : out std_logic;
|
||||
d_out : out std_logic;
|
||||
i_out : out std_logic );
|
||||
end data_oper;
|
||||
|
||||
architecture gideon of data_oper is
|
||||
signal shift_sel : std_logic_vector(1 downto 0) := "00";
|
||||
signal shift_din : std_logic_vector(7 downto 0) := X"00";
|
||||
signal shift_dout: std_logic_vector(7 downto 0) := X"00";
|
||||
signal alu_data_a: std_logic_vector(7 downto 0) := X"00";
|
||||
signal row0_n : std_logic;
|
||||
signal row0_v : std_logic;
|
||||
signal row0_z : std_logic;
|
||||
signal row0_c : std_logic;
|
||||
|
||||
signal shft_n : std_logic;
|
||||
signal shft_z : std_logic;
|
||||
signal shft_c : std_logic;
|
||||
|
||||
signal alu_n : std_logic;
|
||||
signal alu_v : std_logic;
|
||||
signal alu_z : std_logic;
|
||||
signal alu_c : std_logic;
|
||||
|
||||
signal impl_n : std_logic;
|
||||
signal impl_z : std_logic;
|
||||
signal impl_c : std_logic;
|
||||
signal impl_v : std_logic;
|
||||
signal impl_i : std_logic;
|
||||
signal impl_d : std_logic;
|
||||
|
||||
signal shift_en : std_logic;
|
||||
signal alu_en : std_logic;
|
||||
signal impl_en : std_logic;
|
||||
signal impl_flags: boolean;
|
||||
begin
|
||||
shift_sel <= shifter_in_select(inst);
|
||||
with shift_sel select shift_din <=
|
||||
data_in when "01",
|
||||
a_reg when "10",
|
||||
data_in and a_reg when "11",
|
||||
X"FF" when others;
|
||||
|
||||
shift_en <= '1' when is_shift(inst) else '0';
|
||||
alu_en <= '1' when is_alu(inst) else '0';
|
||||
|
||||
row0: entity work.bit_cpx_cpy
|
||||
port map (
|
||||
operation => inst(7 downto 5),
|
||||
enable => '1',
|
||||
|
||||
n_in => n_in,
|
||||
v_in => v_in,
|
||||
z_in => z_in,
|
||||
c_in => c_in,
|
||||
|
||||
data_in => data_in,
|
||||
a_reg => a_reg,
|
||||
x_reg => x_reg,
|
||||
y_reg => y_reg,
|
||||
|
||||
n_out => row0_n,
|
||||
v_out => row0_v,
|
||||
z_out => row0_z,
|
||||
c_out => row0_c );
|
||||
|
||||
shft: entity work.shifter
|
||||
port map (
|
||||
operation => inst(7 downto 5),
|
||||
enable => shift_en,
|
||||
|
||||
c_in => c_in,
|
||||
n_in => n_in,
|
||||
z_in => z_in,
|
||||
|
||||
data_in => shift_din,
|
||||
|
||||
c_out => shft_c,
|
||||
n_out => shft_n,
|
||||
z_out => shft_z,
|
||||
|
||||
data_out => shift_dout );
|
||||
|
||||
alu_data_a <= a_reg and x_reg when x_to_alu(inst) else a_reg;
|
||||
|
||||
alu1: entity work.alu
|
||||
generic map (
|
||||
support_bcd => support_bcd )
|
||||
port map (
|
||||
operation => inst(7 downto 5),
|
||||
enable => alu_en,
|
||||
|
||||
n_in => shft_n,
|
||||
v_in => v_in,
|
||||
z_in => shft_z,
|
||||
c_in => shft_c,
|
||||
d_in => d_in,
|
||||
|
||||
data_a => alu_data_a,
|
||||
data_b => shift_dout,
|
||||
|
||||
n_out => alu_n,
|
||||
v_out => alu_v,
|
||||
z_out => alu_z,
|
||||
c_out => alu_c,
|
||||
|
||||
data_out => alu_out );
|
||||
|
||||
mem_out <= shift_dout;
|
||||
|
||||
impl_en <= '1' when is_implied(inst) else '0';
|
||||
impl_flags <= is_implied(inst) and (inst(4)='1' or inst(7)='1');
|
||||
|
||||
impl: entity work.implied
|
||||
port map (
|
||||
inst => inst,
|
||||
enable => impl_en,
|
||||
|
||||
c_in => c_in,
|
||||
i_in => i_in,
|
||||
n_in => n_in,
|
||||
z_in => z_in,
|
||||
d_in => d_in,
|
||||
v_in => v_in,
|
||||
|
||||
reg_a => a_reg,
|
||||
reg_x => x_reg,
|
||||
reg_y => y_reg,
|
||||
reg_s => s_reg,
|
||||
|
||||
i_out => impl_i,
|
||||
d_out => impl_d,
|
||||
c_out => impl_c,
|
||||
n_out => impl_n,
|
||||
z_out => impl_z,
|
||||
v_out => impl_v,
|
||||
|
||||
set_a => set_a,
|
||||
set_x => set_x,
|
||||
set_y => set_y,
|
||||
set_s => set_s,
|
||||
|
||||
data_out => impl_out );
|
||||
|
||||
n_out <= impl_n when impl_flags else row0_n when inst(1 downto 0)="00" else alu_n;
|
||||
v_out <= impl_v when impl_flags else row0_v when inst(1 downto 0)="00" else alu_v;
|
||||
z_out <= impl_z when impl_flags else row0_z when inst(1 downto 0)="00" else alu_z;
|
||||
c_out <= impl_c when impl_flags else row0_c when inst(1 downto 0)="00" else alu_c;
|
||||
i_out <= impl_i when impl_flags else i_in;
|
||||
d_out <= impl_d when impl_flags else d_in;
|
||||
|
||||
end gideon;
|
||||
114
Commodore - 64_MiST/rtl/c1541/cpu/implied.vhd
Normal file
114
Commodore - 64_MiST/rtl/c1541/cpu/implied.vhd
Normal file
@@ -0,0 +1,114 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity implied is
|
||||
port (
|
||||
inst : in std_logic_vector(7 downto 0);
|
||||
enable : in std_logic;
|
||||
|
||||
c_in : in std_logic;
|
||||
i_in : in std_logic;
|
||||
n_in : in std_logic;
|
||||
z_in : in std_logic;
|
||||
d_in : in std_logic;
|
||||
v_in : in std_logic;
|
||||
|
||||
reg_a : in std_logic_vector(7 downto 0);
|
||||
reg_x : in std_logic_vector(7 downto 0);
|
||||
reg_y : in std_logic_vector(7 downto 0);
|
||||
reg_s : in std_logic_vector(7 downto 0);
|
||||
|
||||
c_out : out std_logic;
|
||||
i_out : out std_logic;
|
||||
n_out : out std_logic;
|
||||
z_out : out std_logic;
|
||||
d_out : out std_logic;
|
||||
v_out : out std_logic;
|
||||
|
||||
set_a : out std_logic;
|
||||
set_x : out std_logic;
|
||||
set_y : out std_logic;
|
||||
set_s : out std_logic;
|
||||
|
||||
data_out : out std_logic_vector(7 downto 0));
|
||||
|
||||
end implied;
|
||||
|
||||
architecture gideon of implied is
|
||||
type t_int4_array is array(natural range <>) of integer range 0 to 3;
|
||||
-- ROMS for the upper (negative) implied instructions
|
||||
constant reg_sel_rom : t_int4_array(0 to 15) := ( 2,0,2,1,1,0,1,1,2,0,2,1,1,3,1,1 ); -- 0=A, 1=X, 2=Y, 3=S
|
||||
constant decr_rom : std_logic_vector(0 to 15) := "1000001000000000";
|
||||
constant incr_rom : std_logic_vector(0 to 15) := "0011000000000000";
|
||||
constant nz_flags : std_logic_vector(0 to 15) := "1111111010000100";
|
||||
constant v_flag : std_logic_vector(0 to 15) := "0000000001000000";
|
||||
constant d_flag : std_logic_vector(0 to 15) := "0000000000110000";
|
||||
constant set_a_rom : std_logic_vector(0 to 15) := "0000100010000000";
|
||||
constant set_x_rom : std_logic_vector(0 to 15) := "0001011000000100";
|
||||
constant set_y_rom : std_logic_vector(0 to 15) := "1110000000000000";
|
||||
constant set_s_rom : std_logic_vector(0 to 15) := "0000000000001000";
|
||||
|
||||
-- ROMS for the lower (positive) implied instructions
|
||||
constant shft_rom : std_logic_vector(0 to 15) := "0000111100000000";
|
||||
constant c_flag : std_logic_vector(0 to 15) := "0000000011000000";
|
||||
constant i_flag : std_logic_vector(0 to 15) := "0000000000110000";
|
||||
|
||||
signal selected_reg : std_logic_vector(7 downto 0) := X"00";
|
||||
signal operation : integer range 0 to 15;
|
||||
signal reg_sel : integer range 0 to 3;
|
||||
signal result : std_logic_vector(7 downto 0) := X"00";
|
||||
signal add : std_logic_vector(7 downto 0) := X"00";
|
||||
signal carry : std_logic := '0';
|
||||
signal zero : std_logic := '0';
|
||||
|
||||
signal n_hi : std_logic;
|
||||
signal z_hi : std_logic;
|
||||
signal v_hi : std_logic;
|
||||
signal d_hi : std_logic;
|
||||
|
||||
signal n_lo : std_logic;
|
||||
signal z_lo : std_logic;
|
||||
signal c_lo : std_logic;
|
||||
signal i_lo : std_logic;
|
||||
begin
|
||||
operation <= conv_integer(inst(4) & inst(1) & inst(6 downto 5));
|
||||
reg_sel <= reg_sel_rom(operation);
|
||||
with reg_sel select selected_reg <=
|
||||
reg_a when 0,
|
||||
reg_x when 1,
|
||||
reg_y when 2,
|
||||
reg_s when others;
|
||||
|
||||
add <= (others => decr_rom(operation));
|
||||
carry <= incr_rom(operation);
|
||||
|
||||
result <= selected_reg + add + carry;
|
||||
|
||||
zero <= '1' when result = X"00" else '0';
|
||||
|
||||
data_out <= result;
|
||||
|
||||
n_hi <= result(7) when nz_flags(operation)='1' else n_in;
|
||||
z_hi <= zero when nz_flags(operation)='1' else z_in;
|
||||
v_hi <= '0' when v_flag(operation)='1' else v_in;
|
||||
d_hi <= inst(5) when d_flag(operation)='1' else d_in;
|
||||
-- in high, C and I are never set
|
||||
|
||||
c_lo <= inst(5) when c_flag(operation)='1' else c_in;
|
||||
i_lo <= inst(5) when i_flag(operation)='1' else i_in;
|
||||
-- in low, V, N, Z and D are never set
|
||||
|
||||
set_a <= set_a_rom(operation) and inst(7) and enable;
|
||||
set_x <= set_x_rom(operation) and inst(7) and enable;
|
||||
set_y <= set_y_rom(operation) and inst(7) and enable;
|
||||
set_s <= set_s_rom(operation) and inst(7) and enable;
|
||||
|
||||
c_out <= c_in when inst(7)='1' else c_lo; -- C can only be set in lo
|
||||
i_out <= i_in when inst(7)='1' else i_lo; -- I can only be set in lo
|
||||
v_out <= v_hi when inst(7)='1' else v_in; -- V can only be set in hi
|
||||
d_out <= d_hi when inst(7)='1' else d_in; -- D can only be set in hi
|
||||
n_out <= n_hi when inst(7)='1' else n_in; -- N can only be set in hi
|
||||
z_out <= z_hi when inst(7)='1' else z_in; -- Z can only be set in hi
|
||||
|
||||
end gideon;
|
||||
248
Commodore - 64_MiST/rtl/c1541/cpu/pkg_6502_decode.vhd
Normal file
248
Commodore - 64_MiST/rtl/c1541/cpu/pkg_6502_decode.vhd
Normal file
@@ -0,0 +1,248 @@
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
package pkg_6502_decode is
|
||||
|
||||
function is_absolute(inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function is_abs_jump(inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function is_immediate(inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function is_implied(inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function is_stack(inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function is_push(inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function is_zeropage(inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function is_indirect(inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function is_relative(inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function is_load(inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function is_store(inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function is_shift(inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function is_alu(inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function is_rmw(inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function is_jump(inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function is_postindexed(inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function is_illegal(inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
|
||||
function stack_idx(inst: std_logic_vector(7 downto 0)) return std_logic_vector;
|
||||
|
||||
constant c_stack_idx_brk : std_logic_vector(1 downto 0) := "00";
|
||||
constant c_stack_idx_jsr : std_logic_vector(1 downto 0) := "01";
|
||||
constant c_stack_idx_rti : std_logic_vector(1 downto 0) := "10";
|
||||
constant c_stack_idx_rts : std_logic_vector(1 downto 0) := "11";
|
||||
|
||||
function select_index_y (inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function store_a_from_alu (inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function load_a (inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function load_x (inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function load_y (inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
function shifter_in_select (inst: std_logic_vector(7 downto 0)) return std_logic_vector;
|
||||
function x_to_alu (inst: std_logic_vector(7 downto 0)) return boolean;
|
||||
end;
|
||||
|
||||
package body pkg_6502_decode is
|
||||
|
||||
function is_absolute(inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
-- 4320 = X11X | 1101
|
||||
if inst(3 downto 2)="11" then
|
||||
return true;
|
||||
elsif inst(4 downto 2)="110" and inst(0)='1' then
|
||||
return true;
|
||||
end if;
|
||||
return false;
|
||||
end function;
|
||||
|
||||
function is_jump(inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
return inst(7 downto 6)="01" and inst(3 downto 0)=X"C";
|
||||
end function;
|
||||
|
||||
function is_immediate(inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
-- 76543210 = 1XX000X0
|
||||
if inst(7)='1' and inst(4 downto 2)="000" and inst(0)='0' then
|
||||
return true;
|
||||
-- 76543210 = XXX010X1
|
||||
elsif inst(4 downto 2)="010" and inst(0)='1' then
|
||||
return true;
|
||||
end if;
|
||||
return false;
|
||||
end function;
|
||||
|
||||
function is_implied(inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
-- 4320 = X100
|
||||
return inst(3 downto 2)="10" and inst(0)='0';
|
||||
end function;
|
||||
|
||||
function is_stack(inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
-- 76543210
|
||||
-- 0xx0x000
|
||||
return inst(7)='0' and inst(4)='0' and inst(2 downto 0)="000";
|
||||
end function;
|
||||
|
||||
function is_push(inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
-- we already know it's a stack operation, so only the direction is important
|
||||
return inst(5)='0';
|
||||
end function;
|
||||
|
||||
function is_zeropage(inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
if inst(3 downto 2)="01" then
|
||||
return true;
|
||||
elsif inst(3 downto 2)="00" and inst(0)='1' then
|
||||
return true;
|
||||
end if;
|
||||
return false;
|
||||
end function;
|
||||
|
||||
function is_indirect(inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
return (inst(3 downto 2)="00" and inst(0)='1');
|
||||
end function;
|
||||
|
||||
function is_relative(inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
return (inst(4 downto 0)="10000");
|
||||
end function;
|
||||
|
||||
function is_store(inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
return (inst(7 downto 5)="100");
|
||||
end function;
|
||||
|
||||
function is_shift(inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
if inst(7)='1' and inst(4 downto 2)="010" then
|
||||
return false;
|
||||
end if;
|
||||
return (inst(1)='1');
|
||||
end function;
|
||||
|
||||
function is_alu(inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
if inst(7)='0' and inst(4 downto 1)="0101" then
|
||||
return false;
|
||||
end if;
|
||||
return (inst(0)='1');
|
||||
end function;
|
||||
|
||||
function is_load(inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
return not is_store(inst) and not is_rmw(inst);
|
||||
end function;
|
||||
|
||||
function is_rmw(inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
return inst(1)='1' and inst(7 downto 6)/="10";
|
||||
end function;
|
||||
|
||||
function is_abs_jump(inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
return is_jump(inst) and inst(5)='0';
|
||||
end function;
|
||||
|
||||
function is_postindexed(inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
return inst(4)='1';
|
||||
end function;
|
||||
|
||||
function stack_idx(inst: std_logic_vector(7 downto 0)) return std_logic_vector is
|
||||
begin
|
||||
return inst(6 downto 5);
|
||||
end function;
|
||||
|
||||
function select_index_y (inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
if inst(4)='1' and inst(2)='0' and inst(0)='1' then -- XXX1X0X1
|
||||
return true;
|
||||
elsif inst(7 downto 6)="10" and inst(2 downto 1)="11" then -- 10XXX11X
|
||||
return true;
|
||||
end if;
|
||||
return false;
|
||||
end function;
|
||||
|
||||
-- function flags_bit_group (inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
-- begin
|
||||
-- return inst(2 downto 0)="100";
|
||||
-- end function;
|
||||
--
|
||||
-- function flags_alu_group (inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
-- begin
|
||||
-- return inst(1 downto 0)="01"; -- could also choose not to look at bit 1 (overlap)
|
||||
-- end function;
|
||||
--
|
||||
-- function flags_shift_group (inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
-- begin
|
||||
-- return inst(1 downto 0)="10"; -- could also choose not to look at bit 0 (overlap)
|
||||
-- end function;
|
||||
|
||||
function load_a (inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
return (inst = X"68");
|
||||
end function;
|
||||
|
||||
function store_a_from_alu (inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
-- 0XXXXXX1 or alu operations "lo"
|
||||
-- 1X100001 or alu operations "hi" (except store and cmp)
|
||||
-- 0XX01010 (implied)
|
||||
return (inst(7)='0' and inst(4 downto 0)="01010") or
|
||||
(inst(7)='0' and inst(0)='1') or
|
||||
(inst(7)='1' and inst(0)='1' and inst(5)='1');
|
||||
end function;
|
||||
|
||||
function load_x (inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
-- 101XXX1X or 1100101- (for SAX #)
|
||||
if inst(7 downto 1)="1100101" then
|
||||
return true;
|
||||
end if;
|
||||
return inst(7 downto 5)="101" and inst(1)='1' and not is_implied(inst);
|
||||
end function;
|
||||
|
||||
function load_y (inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
-- 101XXX00
|
||||
return inst(7 downto 5)="101" and inst(1 downto 0)="00" and not is_implied(inst);
|
||||
end function;
|
||||
|
||||
function shifter_in_select (inst: std_logic_vector(7 downto 0)) return std_logic_vector is
|
||||
begin
|
||||
-- 00 = none, 01 = memory, 10 = A, 11 = A & M
|
||||
if inst(4 downto 2)="010" and inst(7)='0' then
|
||||
return inst(1 downto 0);
|
||||
end if;
|
||||
return "01";
|
||||
end function;
|
||||
|
||||
-- function shifter_in_select (inst: std_logic_vector(7 downto 0)) return std_logic_vector is
|
||||
-- begin
|
||||
-- -- 0=memory, 1=A
|
||||
-- if inst(4 downto 1)="0101" and inst(7)='0' then
|
||||
-- return "01";
|
||||
-- end if;
|
||||
-- return "10";
|
||||
-- end function;
|
||||
|
||||
function is_illegal (inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
type t_my16bit_array is array(natural range <>) of std_logic_vector(15 downto 0);
|
||||
constant c_illegal_map : t_my16bit_array(0 to 15) := (
|
||||
X"989C", X"9C9C", X"888C", X"9C9C", X"889C", X"9C9C", X"889C", X"9C9C",
|
||||
X"8A8D", X"D88C", X"8888", X"888C", X"888C", X"9C9C", X"888C", X"9C9C" );
|
||||
variable row : std_logic_vector(15 downto 0);
|
||||
begin
|
||||
row := c_illegal_map(conv_integer(inst(7 downto 4)));
|
||||
return (row(conv_integer(inst(3 downto 0))) = '1');
|
||||
end function;
|
||||
|
||||
function x_to_alu (inst: std_logic_vector(7 downto 0)) return boolean is
|
||||
begin
|
||||
-- 1-00101- 8A,8B,CA,CB
|
||||
return inst(5 downto 1)="00101" and inst(7)='1';
|
||||
end function;
|
||||
|
||||
end;
|
||||
18
Commodore - 64_MiST/rtl/c1541/cpu/pkg_6502_defs.vhd
Normal file
18
Commodore - 64_MiST/rtl/c1541/cpu/pkg_6502_defs.vhd
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
package pkg_6502_defs is
|
||||
|
||||
subtype t_amux is integer range 0 to 3;
|
||||
constant c_amux_vector : t_amux := 0;
|
||||
constant c_amux_addr : t_amux := 1;
|
||||
constant c_amux_stack : t_amux := 2;
|
||||
constant c_amux_pc : t_amux := 3;
|
||||
|
||||
type t_pc_oper is (keep, increment, copy, from_alu);
|
||||
type t_adl_oper is (keep, increment, add_idx, load_bus, copy_dreg);
|
||||
type t_adh_oper is (keep, increment, clear, load_bus);
|
||||
type t_sp_oper is (keep, increment, decrement);
|
||||
type t_dout_mux is (reg_d, reg_accu, reg_axy, reg_flags, reg_pcl, reg_pch, shift_res);
|
||||
end;
|
||||
88
Commodore - 64_MiST/rtl/c1541/cpu/pkg_6502_opcodes.vhd
Normal file
88
Commodore - 64_MiST/rtl/c1541/cpu/pkg_6502_opcodes.vhd
Normal file
@@ -0,0 +1,88 @@
|
||||
|
||||
package pkg_6502_opcodes is
|
||||
|
||||
type t_opcode_array is array(0 to 255) of string(1 to 13);
|
||||
|
||||
constant opcode_array : t_opcode_array := (
|
||||
|
||||
"BRK ", "ORA ($nn,X) ", "HLT* ", "ASO*($nn,X) ",
|
||||
"BOT*$nn ", "ORA $nn ", "ASL $nn ", "ASO*$nn ",
|
||||
"PHP ", "ORA # ", "ASL A ", "ORA*# ",
|
||||
"BOT*$nnnnn ", "ORA $nnnn ", "ASL $nnnn ", "ASO*$nnnn ",
|
||||
|
||||
"BPL rel ", "ORA ($nn),Y ", "HLT* ", "ASO*($nn),Y ",
|
||||
"BOT*$nn,X ", "ORA $nn,X ", "ASL $nn,X ", "ASO*$nn,X ",
|
||||
"CLC ", "ORA $nnnn,Y ", "NOP* ", "ASO*$nnnn,Y ",
|
||||
"BOT*$nnnn,X ", "ORA $nnnn,X ", "ASL $nnnn,X ", "ASO*$nnnn,X ",
|
||||
|
||||
"JSR $nnnn ", "AND ($nn,X) ", "HLT* ", "RLA*($nn,X) ",
|
||||
"BIT $nn ", "AND $nn ", "ROL $nn ", "RLA*$nn ",
|
||||
"PLP ", "AND # ", "ROL A ", "AND*# ",
|
||||
"BIT $nnnn ", "AND $nnnn ", "ROL $nnnn ", "RLA*$nnnn ",
|
||||
|
||||
"BMI rel ", "AND ($nn),Y ", "HLT* ", "RLA*($nn),Y ",
|
||||
"BIT*$nn,X ", "AND $nn,X ", "ROL $nn,X ", "RLA*$nn,X ",
|
||||
"SEC ", "AND $nnnn,Y ", "NOP* ", "RLA*$nnnn,Y ",
|
||||
"BIT*$nnnn,X ", "AND $nnnn,X ", "ROL $nnnn,X ", "RLA*$nnnn,X ",
|
||||
|
||||
"RTI ", "EOR ($nn,X) ", "HLT* ", "LSE*($nn,X) ",
|
||||
"RDM* ", "EOR $nn ", "LSR $nn ", "LSE*$nn ",
|
||||
"PHA ", "EOR # ", "LSR A ", "EOR*# ",
|
||||
"JMP $nnnn ", "EOR $nnnn ", "LSR $nnnn ", "LSE*$nnnn ",
|
||||
|
||||
"BVC rel ", "EOR ($nn),Y ", "HLT* ", "LSE*($nn),Y ",
|
||||
"RDM* ", "EOR $nn,X ", "LSR $nn,X ", "LSE*$nn,X ",
|
||||
"CLI ", "EOR $nnnn,Y ", "NOP* ", "LSE*$nnnn,Y ",
|
||||
"JMP*$nnnn ", "EOR $nnnn,X ", "LSR $nnnn,X ", "LSE*$nnnn,X ",
|
||||
|
||||
"RTS ", "ADC ($nn,X) ", "HLT* ", "RRA*($nn,X) ",
|
||||
"RDM* ", "ADC $nn ", "ROR $nn ", "RRA*$nn ",
|
||||
"PLA ", "ADC # ", "ROR A ", "ADC*# ",
|
||||
"JMP ($nnnn) ", "ADC $nnnn ", "ROR $nnnn ", "RRA*$nnnn ",
|
||||
|
||||
"BVS rel ", "ADC ($nn),Y ", "HLT* ", "RRA*($nn),Y ",
|
||||
"RDM* ", "ADC $nn,X ", "ROR $nn,X ", "RRA*$nn,X ",
|
||||
"SEI ", "ADC $nnnn,Y ", "NOP* ", "RRA*$nnnn,Y ",
|
||||
"JMP*($nnnn,X)", "ADC $nnnn,X ", "ROR $nnnn,X ", "RRA*$nnnn,X ",
|
||||
|
||||
"SKB* ", "STA ($nn,X) ", "SKB* ", "AXS*($nn,X) ",
|
||||
"STY $nn ", "STA $nn ", "STX $nn ", "AXS*$nn ",
|
||||
"DEY ", "SKB* ", "TXA ", "???* ",
|
||||
"STY $nnnn ", "STA $nnnn ", "STX $nnnn ", "AXS*$nnnn ",
|
||||
|
||||
"BCC ", "STA ($nn),Y ", "HLT* ", "AXS*($nn),Y ",
|
||||
"STY $nn,X ", "STA $nn,X ", "STX $nn,Y ", "AXS*$nn,Y ",
|
||||
"TYA ", "STA $nnnn,Y ", "TXS ", "AXS*$nnnn,Y ",
|
||||
"STY*$nnnn,X ", "STA $nnnn,X ", "STX*$nnnn,Y ", "AXS*$nnnn,Y ",
|
||||
|
||||
"LDY # ", "LDA ($nn,X) ", "LDX # ", "LAX*($nn,X) ",
|
||||
"LDY $nn ", "LDA $nn ", "LDX $nn ", "LAX*$nn ",
|
||||
"TAY ", "LDA # ", "TAX ", "LAX*# ",
|
||||
"LDY $nnnn ", "LDA $nnnn ", "LDX $nnnn ", "LAX*$nnnn ",
|
||||
|
||||
"BCS ", "LDA ($nn),Y ", "HLT* ", "LAX*($nn),Y ",
|
||||
"LDY $nn,X ", "LDA $nn,X ", "LDX $nn,Y ", "LAX*$nn,Y ",
|
||||
"CLV ", "LDA $nnnn,Y ", "TSX ", "LAX*$nnnn,Y ",
|
||||
"LDY $nnnn,X ", "LDA $nnnn,X ", "LDX $nnnn,Y ", "LAX*$nnnn,Y ",
|
||||
|
||||
"CPY # ", "CMP ($nn,X) ", "SKB* ", "DCM*($nn,X) ",
|
||||
"CPY $nn ", "CMP $nn ", "DEC $nn ", "DCM*$nn ",
|
||||
"INY ", "CMP # ", "DEX ", "SAX*# (used!)",
|
||||
"CPY $nnnn ", "CMP $nnnn ", "DEC $nnnn ", "DCM*$nnnn ",
|
||||
|
||||
"BNE ", "CMP ($nn),Y ", "HLT* ", "DCM*($nn),Y ",
|
||||
"RDM* ", "CMP $nn,X ", "DEC $nn,X ", "DCM*$nn,X ",
|
||||
"CLD ", "CMP $nnnn,Y ", "NOP* ", "DCM*$nnnn,Y ",
|
||||
"RDM*$nnnn,X ", "CMP $nnnn,X ", "DEC $nnnn,X ", "DCM*$nnnn,X ",
|
||||
|
||||
"CPX # ", "SBC ($nn,X) ", "SKB* ", "INS*($nn,X) ",
|
||||
"CPX $nn ", "SBC $nn ", "INC $nn ", "INS*$nn ",
|
||||
"INX ", "SBC # ", "NOP ", "SBC*# ",
|
||||
"CPX $nnnn ", "SBC $nnnn ", "INC $nnnn ", "INS*$nnnn ",
|
||||
|
||||
"BEQ ", "SBC ($nn),Y ", "HLT* ", "INS*($nn),Y ",
|
||||
"RDM* ", "SBC $nn,X ", "INC $nn,X ", "INS*$nn,X ",
|
||||
"SED ", "SBC $nnnn,Y ", "NOP* ", "INS*$nnnn,Y ",
|
||||
"RDM*$nnnn,X ", "SBC $nnnn,X ", "INC $nnnn,X ", "INS*$nnnn,X " );
|
||||
|
||||
end;
|
||||
472
Commodore - 64_MiST/rtl/c1541/cpu/proc_control.vhd
Normal file
472
Commodore - 64_MiST/rtl/c1541/cpu/proc_control.vhd
Normal file
@@ -0,0 +1,472 @@
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library work;
|
||||
use work.pkg_6502_defs.all;
|
||||
use work.pkg_6502_decode.all;
|
||||
|
||||
entity proc_control is
|
||||
port (
|
||||
clock : in std_logic;
|
||||
clock_en : in std_logic;
|
||||
reset : in std_logic;
|
||||
|
||||
interrupt : in std_logic;
|
||||
i_reg : in std_logic_vector(7 downto 0);
|
||||
index_carry : in std_logic;
|
||||
pc_carry : in std_logic;
|
||||
branch_taken : in boolean;
|
||||
|
||||
sync : out std_logic;
|
||||
dummy_cycle : out std_logic;
|
||||
set_b : out std_logic;
|
||||
latch_dreg : out std_logic;
|
||||
copy_d2p : out std_logic;
|
||||
reg_update : out std_logic;
|
||||
rwn : out std_logic;
|
||||
vect_bit : out std_logic := '0';
|
||||
a16 : out std_logic;
|
||||
a_mux : out t_amux := c_amux_pc;
|
||||
dout_mux : out t_dout_mux;
|
||||
pc_oper : out t_pc_oper;
|
||||
s_oper : out t_sp_oper;
|
||||
adl_oper : out t_adl_oper;
|
||||
adh_oper : out t_adh_oper );
|
||||
|
||||
end proc_control;
|
||||
|
||||
|
||||
architecture gideon of proc_control is
|
||||
|
||||
type t_state is (fetch, decode, absolute, abs_hi, abs_fix, branch, branch_fix,
|
||||
indir1, indir2, jump_sub, jump, retrn, rmw1, rmw2, vector, startup,
|
||||
zp, zp_idx, zp_indir, push1, push2, push3, pull1, pull2, pull3 );
|
||||
|
||||
signal state : t_state;
|
||||
signal next_state : t_state;
|
||||
|
||||
signal next_cp_p : std_logic;
|
||||
signal next_rwn : std_logic;
|
||||
signal next_dreg : std_logic;
|
||||
signal next_amux : t_amux;
|
||||
signal next_dout : t_dout_mux;
|
||||
signal next_set_b : std_logic;
|
||||
signal next_dummy : std_logic;
|
||||
signal vectoring : std_logic;
|
||||
begin
|
||||
-- combinatroial process
|
||||
process(state, i_reg, index_carry, pc_carry, branch_taken, interrupt, vectoring)
|
||||
variable v_stack_idx : std_logic_vector(1 downto 0);
|
||||
begin
|
||||
-- defaults
|
||||
sync <= '0';
|
||||
pc_oper <= increment;
|
||||
next_amux <= c_amux_pc;
|
||||
next_rwn <= '1';
|
||||
next_state <= state;
|
||||
adl_oper <= keep;
|
||||
adh_oper <= keep;
|
||||
s_oper <= keep;
|
||||
next_dreg <= '1';
|
||||
next_cp_p <= '0';
|
||||
next_dout <= reg_d;
|
||||
next_set_b <= '0';
|
||||
next_dummy <= '0';
|
||||
|
||||
v_stack_idx := stack_idx(i_reg);
|
||||
|
||||
case state is
|
||||
when fetch =>
|
||||
sync <= '1';
|
||||
|
||||
if interrupt='1' then
|
||||
pc_oper <= keep;
|
||||
next_rwn <= '0';
|
||||
next_dout <= reg_pch;
|
||||
next_state <= push1;
|
||||
next_amux <= c_amux_stack;
|
||||
else
|
||||
next_state <= decode;
|
||||
next_set_b <= '1';
|
||||
end if;
|
||||
|
||||
when decode =>
|
||||
adl_oper <= load_bus;
|
||||
adh_oper <= clear;
|
||||
|
||||
if is_absolute(i_reg) then
|
||||
if is_abs_jump(i_reg) then
|
||||
next_state <= jump;
|
||||
else
|
||||
next_state <= absolute;
|
||||
end if;
|
||||
elsif is_implied(i_reg) then
|
||||
pc_oper <= keep;
|
||||
if is_stack(i_reg) then -- PHP, PLP, PHA, PLA
|
||||
next_amux <= c_amux_stack;
|
||||
case v_stack_idx is
|
||||
when "00" => -- PHP
|
||||
next_state <= push3;
|
||||
next_rwn <= '0';
|
||||
next_dout <= reg_flags;
|
||||
|
||||
when "10" => -- PHA
|
||||
next_state <= push3;
|
||||
next_rwn <= '0';
|
||||
next_dout <= reg_accu;
|
||||
|
||||
when others =>
|
||||
next_state <= pull1;
|
||||
end case;
|
||||
else
|
||||
next_state <= fetch;
|
||||
end if;
|
||||
elsif is_zeropage(i_reg) then
|
||||
next_amux <= c_amux_addr;
|
||||
if is_indirect(i_reg) then
|
||||
if is_postindexed(i_reg) then
|
||||
next_state <= zp_indir;
|
||||
else
|
||||
next_state <= zp;
|
||||
next_dummy <= '1';
|
||||
end if;
|
||||
else
|
||||
next_state <= zp;
|
||||
if is_store(i_reg) and not is_postindexed(i_reg) then
|
||||
next_rwn <= '0';
|
||||
next_dout <= reg_axy;
|
||||
end if;
|
||||
end if;
|
||||
elsif is_relative(i_reg) then
|
||||
next_state <= branch;
|
||||
elsif is_stack(i_reg) then -- non-implied stack operations like BRK, JSR, RTI and RTS
|
||||
next_amux <= c_amux_stack;
|
||||
case v_stack_idx is
|
||||
when c_stack_idx_brk =>
|
||||
-- next_set_b <= '1';
|
||||
next_rwn <= '0';
|
||||
next_dout <= reg_pch;
|
||||
next_state <= push1;
|
||||
when c_stack_idx_jsr =>
|
||||
next_dreg <= '0';
|
||||
next_dout <= reg_pch;
|
||||
next_state <= jump_sub;
|
||||
when c_stack_idx_rti =>
|
||||
next_state <= pull1;
|
||||
when c_stack_idx_rts =>
|
||||
next_state <= pull2;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
elsif is_immediate(i_reg) then
|
||||
next_state <= fetch;
|
||||
end if;
|
||||
|
||||
when absolute =>
|
||||
next_state <= abs_hi;
|
||||
next_amux <= c_amux_addr;
|
||||
adh_oper <= load_bus;
|
||||
if is_postindexed(i_reg) then
|
||||
adl_oper <= add_idx;
|
||||
elsif not is_zeropage(i_reg) then
|
||||
if is_store(i_reg) then
|
||||
next_rwn <='0';
|
||||
next_dout <= reg_axy;
|
||||
end if;
|
||||
end if;
|
||||
if is_zeropage(i_reg) then
|
||||
pc_oper <= keep;
|
||||
else
|
||||
pc_oper <= increment;
|
||||
end if;
|
||||
|
||||
when abs_hi =>
|
||||
pc_oper <= keep;
|
||||
if is_postindexed(i_reg) then
|
||||
if is_load(i_reg) and index_carry='0' then
|
||||
next_amux <= c_amux_pc;
|
||||
next_state <= fetch;
|
||||
else
|
||||
next_amux <= c_amux_addr;
|
||||
next_state <= abs_fix;
|
||||
if index_carry='1' then
|
||||
adh_oper <= increment;
|
||||
end if;
|
||||
end if;
|
||||
if is_store(i_reg) then
|
||||
next_rwn <= '0';
|
||||
next_dout <= reg_axy;
|
||||
end if;
|
||||
else -- not post-indexed
|
||||
if is_jump(i_reg) then
|
||||
next_amux <= c_amux_addr;
|
||||
next_state <= jump;
|
||||
adl_oper <= increment;
|
||||
elsif is_rmw(i_reg) then
|
||||
next_rwn <= '0';
|
||||
next_dout <= reg_d;
|
||||
next_dummy <= '1';
|
||||
next_state <= rmw1;
|
||||
next_amux <= c_amux_addr;
|
||||
else
|
||||
next_state <= fetch;
|
||||
next_amux <= c_amux_pc;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when abs_fix =>
|
||||
pc_oper <= keep;
|
||||
|
||||
if is_rmw(i_reg) then
|
||||
next_state <= rmw1;
|
||||
next_amux <= c_amux_addr;
|
||||
next_rwn <= '0';
|
||||
next_dout <= reg_d;
|
||||
next_dummy <= '1';
|
||||
else
|
||||
next_state <= fetch;
|
||||
next_amux <= c_amux_pc;
|
||||
end if;
|
||||
|
||||
when branch =>
|
||||
next_amux <= c_amux_pc;
|
||||
if branch_taken then
|
||||
pc_oper <= from_alu; -- add offset
|
||||
next_state <= branch_fix;
|
||||
else
|
||||
pc_oper <= increment;
|
||||
next_state <= decode;
|
||||
sync <= '1';
|
||||
end if;
|
||||
|
||||
when branch_fix =>
|
||||
next_amux <= c_amux_pc;
|
||||
|
||||
if pc_carry='1' then
|
||||
next_state <= fetch;
|
||||
pc_oper <= keep; -- this will fix the PCH, since the carry is set
|
||||
else
|
||||
sync <= '1';
|
||||
next_state <= decode;
|
||||
pc_oper <= increment;
|
||||
end if;
|
||||
|
||||
when indir1 =>
|
||||
pc_oper <= keep;
|
||||
next_state <= indir2;
|
||||
next_amux <= c_amux_addr;
|
||||
adl_oper <= copy_dreg;
|
||||
adh_oper <= load_bus;
|
||||
|
||||
if is_store(i_reg) then
|
||||
next_rwn <= '0';
|
||||
next_dout <= reg_axy;
|
||||
end if;
|
||||
|
||||
when indir2 =>
|
||||
pc_oper <= keep;
|
||||
if is_rmw(i_reg) then
|
||||
next_dummy <= '1';
|
||||
next_rwn <= '0';
|
||||
next_dout <= reg_d;
|
||||
next_state <= rmw1;
|
||||
next_amux <= c_amux_addr;
|
||||
else
|
||||
next_state <= fetch;
|
||||
next_amux <= c_amux_pc;
|
||||
end if;
|
||||
|
||||
when jump_sub =>
|
||||
next_state <= push1;
|
||||
pc_oper <= keep;
|
||||
next_dout <= reg_pch;
|
||||
next_rwn <= '0';
|
||||
next_dreg <= '0';
|
||||
next_amux <= c_amux_stack;
|
||||
|
||||
when jump =>
|
||||
pc_oper <= copy;
|
||||
next_amux <= c_amux_pc;
|
||||
if is_stack(i_reg) and v_stack_idx=c_stack_idx_rts and vectoring='0' then
|
||||
next_state <= retrn;
|
||||
else
|
||||
next_state <= fetch;
|
||||
end if;
|
||||
|
||||
when retrn =>
|
||||
pc_oper <= increment;
|
||||
next_state <= fetch;
|
||||
|
||||
when pull1 =>
|
||||
s_oper <= increment;
|
||||
next_state <= pull2;
|
||||
next_amux <= c_amux_stack;
|
||||
pc_oper <= keep;
|
||||
|
||||
when pull2 =>
|
||||
pc_oper <= keep;
|
||||
if is_implied(i_reg) then
|
||||
next_state <= fetch;
|
||||
next_amux <= c_amux_pc;
|
||||
next_cp_p <= not v_stack_idx(1); -- only for PLP
|
||||
else -- it was a stack operation, but not implied (RTS/RTI)
|
||||
s_oper <= increment;
|
||||
next_state <= pull3;
|
||||
next_amux <= c_amux_stack;
|
||||
next_cp_p <= not v_stack_idx(0); -- only for RTI
|
||||
end if;
|
||||
|
||||
when pull3 =>
|
||||
pc_oper <= keep;
|
||||
s_oper <= increment;
|
||||
next_state <= jump;
|
||||
next_amux <= c_amux_stack;
|
||||
|
||||
when push1 =>
|
||||
pc_oper <= keep;
|
||||
s_oper <= decrement;
|
||||
next_state <= push2;
|
||||
next_amux <= c_amux_stack;
|
||||
next_rwn <= '0';
|
||||
next_dreg <= '0';
|
||||
next_dout <= reg_pcl;
|
||||
|
||||
when push2 =>
|
||||
pc_oper <= keep;
|
||||
s_oper <= decrement;
|
||||
if (v_stack_idx=c_stack_idx_jsr) and vectoring='0' then
|
||||
next_state <= jump;
|
||||
next_amux <= c_amux_pc;
|
||||
else
|
||||
next_state <= push3;
|
||||
next_rwn <= '0';
|
||||
next_dout <= reg_flags;
|
||||
next_amux <= c_amux_stack;
|
||||
end if;
|
||||
|
||||
when push3 =>
|
||||
pc_oper <= keep;
|
||||
s_oper <= decrement;
|
||||
if is_implied(i_reg) and vectoring='0' then -- PHP, PHA
|
||||
next_amux <= c_amux_pc;
|
||||
next_state <= fetch;
|
||||
else
|
||||
next_state <= vector;
|
||||
next_amux <= c_amux_vector;
|
||||
end if;
|
||||
|
||||
when rmw1 =>
|
||||
pc_oper <= keep;
|
||||
next_state <= rmw2;
|
||||
next_amux <= c_amux_addr;
|
||||
next_rwn <= '0';
|
||||
next_dout <= shift_res;
|
||||
|
||||
when rmw2 =>
|
||||
pc_oper <= keep;
|
||||
next_state <= fetch;
|
||||
next_amux <= c_amux_pc;
|
||||
|
||||
when vector =>
|
||||
next_state <= jump;
|
||||
pc_oper <= keep;
|
||||
next_amux <= c_amux_vector;
|
||||
|
||||
when startup =>
|
||||
next_state <= vector;
|
||||
pc_oper <= keep;
|
||||
next_amux <= c_amux_vector;
|
||||
|
||||
when zp =>
|
||||
pc_oper <= keep;
|
||||
if is_postindexed(i_reg) or is_indirect(i_reg) then
|
||||
adl_oper <= add_idx;
|
||||
next_state <= zp_idx;
|
||||
next_amux <= c_amux_addr;
|
||||
if is_postindexed(i_reg) and is_store(i_reg) then
|
||||
next_rwn <= '0';
|
||||
next_dout <= reg_axy;
|
||||
end if;
|
||||
elsif is_rmw(i_reg) then
|
||||
next_dummy <= '1';
|
||||
next_state <= rmw1;
|
||||
next_amux <= c_amux_addr;
|
||||
next_rwn <= '0';
|
||||
next_dout <= reg_d;
|
||||
else
|
||||
next_state <= fetch;
|
||||
next_amux <= c_amux_pc;
|
||||
end if;
|
||||
|
||||
when zp_idx =>
|
||||
pc_oper <= keep;
|
||||
if is_indirect(i_reg) then
|
||||
next_state <= indir1;
|
||||
adl_oper <= increment;
|
||||
next_amux <= c_amux_addr;
|
||||
elsif is_rmw(i_reg) then
|
||||
next_state <= rmw1;
|
||||
next_amux <= c_amux_addr;
|
||||
next_rwn <= '0';
|
||||
next_dout <= reg_d;
|
||||
else
|
||||
next_state <= fetch;
|
||||
next_amux <= c_amux_pc;
|
||||
end if;
|
||||
|
||||
when zp_indir =>
|
||||
pc_oper <= keep;
|
||||
next_state <= absolute;
|
||||
next_amux <= c_amux_addr;
|
||||
adl_oper <= increment;
|
||||
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
reg_update <= '1' when (state = fetch) and vectoring='0' and
|
||||
not is_stack(i_reg) and not is_relative(i_reg) else '0';
|
||||
|
||||
vect_bit <= '0' when state = vector else '1';
|
||||
|
||||
process(clock)
|
||||
begin
|
||||
if rising_edge(clock) then
|
||||
if clock_en='1' then
|
||||
state <= next_state;
|
||||
a_mux <= next_amux;
|
||||
dout_mux <= next_dout;
|
||||
rwn <= next_rwn;
|
||||
latch_dreg <= next_dreg and next_rwn; -- disable dreg latch for writes
|
||||
copy_d2p <= next_cp_p;
|
||||
set_b <= next_set_b;
|
||||
dummy_cycle <= next_dummy;
|
||||
|
||||
if next_amux = c_amux_vector or next_amux = c_amux_pc then
|
||||
a16 <= '1';
|
||||
else
|
||||
a16 <= '0';
|
||||
end if;
|
||||
|
||||
if state = fetch then
|
||||
vectoring <= interrupt;
|
||||
end if;
|
||||
end if;
|
||||
if reset='1' then
|
||||
a16 <= '1';
|
||||
state <= startup; --vector;
|
||||
a_mux <= c_amux_vector;
|
||||
rwn <= '1';
|
||||
latch_dreg <= '1';
|
||||
dout_mux <= reg_d;
|
||||
copy_d2p <= '0';
|
||||
set_b <= '0';
|
||||
vectoring <= '0';
|
||||
dummy_cycle <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
end gideon;
|
||||
|
||||
233
Commodore - 64_MiST/rtl/c1541/cpu/proc_core.vhd
Normal file
233
Commodore - 64_MiST/rtl/c1541/cpu/proc_core.vhd
Normal file
@@ -0,0 +1,233 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
|
||||
library work;
|
||||
use work.pkg_6502_defs.all;
|
||||
|
||||
entity proc_core is
|
||||
generic (
|
||||
vector_page : std_logic_vector(15 downto 4) := X"FFF";
|
||||
support_bcd : boolean := true );
|
||||
port(
|
||||
clock : in std_logic;
|
||||
clock_en : in std_logic;
|
||||
reset : in std_logic;
|
||||
|
||||
irq_n : in std_logic := '1';
|
||||
nmi_n : in std_logic := '1';
|
||||
so_n : in std_logic := '1';
|
||||
|
||||
sync_out : out std_logic;
|
||||
pc_out : out std_logic_vector(15 downto 0);
|
||||
inst_out : out std_logic_vector(7 downto 0);
|
||||
addr_out : out std_logic_vector(16 downto 0);
|
||||
data_in : in std_logic_vector(7 downto 0);
|
||||
data_out : out std_logic_vector(7 downto 0);
|
||||
read_write_n : out std_logic );
|
||||
|
||||
end proc_core;
|
||||
|
||||
architecture structural of proc_core is
|
||||
signal index_carry : std_logic;
|
||||
signal pc_carry : std_logic;
|
||||
signal branch_taken : boolean;
|
||||
signal i_reg : std_logic_vector(7 downto 0);
|
||||
signal d_reg : std_logic_vector(7 downto 0);
|
||||
signal a_reg : std_logic_vector(7 downto 0);
|
||||
signal x_reg : std_logic_vector(7 downto 0);
|
||||
signal y_reg : std_logic_vector(7 downto 0);
|
||||
signal s_reg : std_logic_vector(7 downto 0);
|
||||
signal p_reg : std_logic_vector(7 downto 0);
|
||||
|
||||
signal latch_dreg : std_logic;
|
||||
signal reg_update : std_logic;
|
||||
signal copy_d2p : std_logic;
|
||||
signal sync : std_logic;
|
||||
signal rwn : std_logic;
|
||||
signal vect_bit : std_logic;
|
||||
signal a_mux : t_amux;
|
||||
signal pc_oper : t_pc_oper;
|
||||
signal s_oper : t_sp_oper;
|
||||
signal adl_oper : t_adl_oper;
|
||||
signal adh_oper : t_adh_oper;
|
||||
signal dout_mux : t_dout_mux;
|
||||
|
||||
signal alu_out : std_logic_vector(7 downto 0);
|
||||
signal mem_out : std_logic_vector(7 downto 0);
|
||||
signal impl_out : std_logic_vector(7 downto 0);
|
||||
|
||||
signal set_a : std_logic;
|
||||
signal set_x : std_logic;
|
||||
signal set_y : std_logic;
|
||||
signal set_s : std_logic;
|
||||
|
||||
signal vect_addr : std_logic_vector(3 downto 0);
|
||||
signal interrupt : std_logic;
|
||||
|
||||
signal new_flags : std_logic_vector(7 downto 0);
|
||||
signal n_out : std_logic;
|
||||
signal v_out : std_logic;
|
||||
signal c_out : std_logic;
|
||||
signal z_out : std_logic;
|
||||
signal d_out : std_logic;
|
||||
signal i_out : std_logic;
|
||||
signal set_b : std_logic;
|
||||
signal clear_b : std_logic;
|
||||
signal a16 : std_logic;
|
||||
begin
|
||||
inst_out <= i_reg; -- for debug only
|
||||
|
||||
new_flags(7) <= n_out;
|
||||
new_flags(6) <= v_out;
|
||||
new_flags(5) <= '1';
|
||||
new_flags(4) <= p_reg(4);
|
||||
new_flags(3) <= d_out;
|
||||
new_flags(2) <= i_out;
|
||||
new_flags(1) <= z_out;
|
||||
new_flags(0) <= c_out;
|
||||
|
||||
ctrl: entity work.proc_control
|
||||
port map (
|
||||
clock => clock,
|
||||
clock_en => clock_en,
|
||||
reset => reset,
|
||||
|
||||
interrupt => interrupt,
|
||||
i_reg => i_reg,
|
||||
index_carry => index_carry,
|
||||
pc_carry => pc_carry,
|
||||
branch_taken => branch_taken,
|
||||
|
||||
sync => sync,
|
||||
latch_dreg => latch_dreg,
|
||||
reg_update => reg_update,
|
||||
set_b => set_b,
|
||||
copy_d2p => copy_d2p,
|
||||
vect_bit => vect_bit,
|
||||
a16 => a16,
|
||||
rwn => rwn,
|
||||
a_mux => a_mux,
|
||||
dout_mux => dout_mux,
|
||||
pc_oper => pc_oper,
|
||||
s_oper => s_oper,
|
||||
adl_oper => adl_oper,
|
||||
adh_oper => adh_oper );
|
||||
|
||||
oper: entity work.data_oper
|
||||
generic map (
|
||||
support_bcd => support_bcd )
|
||||
port map (
|
||||
inst => i_reg,
|
||||
|
||||
n_in => p_reg(7),
|
||||
v_in => p_reg(6),
|
||||
z_in => p_reg(1),
|
||||
c_in => p_reg(0),
|
||||
d_in => p_reg(3),
|
||||
i_in => p_reg(2),
|
||||
|
||||
data_in => d_reg,
|
||||
a_reg => a_reg,
|
||||
x_reg => x_reg,
|
||||
y_reg => y_reg,
|
||||
s_reg => s_reg,
|
||||
|
||||
alu_out => alu_out,
|
||||
mem_out => mem_out,
|
||||
impl_out => impl_out,
|
||||
|
||||
set_a => set_a,
|
||||
set_x => set_x,
|
||||
set_y => set_y,
|
||||
set_s => set_s,
|
||||
|
||||
n_out => n_out,
|
||||
v_out => v_out,
|
||||
z_out => z_out,
|
||||
c_out => c_out,
|
||||
d_out => d_out,
|
||||
i_out => i_out );
|
||||
|
||||
regs: entity work.proc_registers
|
||||
generic map (
|
||||
vector_page => vector_page )
|
||||
port map (
|
||||
clock => clock,
|
||||
clock_en => clock_en,
|
||||
reset => reset,
|
||||
|
||||
-- package pins
|
||||
data_in => data_in,
|
||||
data_out => data_out,
|
||||
so_n => so_n,
|
||||
|
||||
-- data from "data_oper"
|
||||
alu_data => alu_out,
|
||||
mem_data => mem_out,
|
||||
new_flags => new_flags,
|
||||
|
||||
-- from implied handler
|
||||
set_a => set_a,
|
||||
set_x => set_x,
|
||||
set_y => set_y,
|
||||
set_s => set_s,
|
||||
set_data => impl_out,
|
||||
|
||||
-- from interrupt controller
|
||||
vect_addr => vect_addr,
|
||||
interrupt => interrupt,
|
||||
set_b => set_b,
|
||||
clear_b => clear_b,
|
||||
|
||||
-- from processor state machine and decoder
|
||||
sync => sync,
|
||||
latch_dreg => latch_dreg,
|
||||
vect_bit => vect_bit,
|
||||
reg_update => reg_update,
|
||||
copy_d2p => copy_d2p,
|
||||
a_mux => a_mux,
|
||||
dout_mux => dout_mux,
|
||||
pc_oper => pc_oper,
|
||||
s_oper => s_oper,
|
||||
adl_oper => adl_oper,
|
||||
adh_oper => adh_oper,
|
||||
|
||||
-- outputs to processor state machine
|
||||
i_reg => i_reg,
|
||||
index_carry => index_carry,
|
||||
pc_carry => pc_carry,
|
||||
branch_taken => branch_taken,
|
||||
|
||||
-- register outputs
|
||||
addr_out => addr_out(15 downto 0),
|
||||
|
||||
d_reg => d_reg,
|
||||
a_reg => a_reg,
|
||||
x_reg => x_reg,
|
||||
y_reg => y_reg,
|
||||
s_reg => s_reg,
|
||||
p_reg => p_reg,
|
||||
pc_out => pc_out );
|
||||
|
||||
intr: entity work.proc_interrupt
|
||||
port map (
|
||||
clock => clock,
|
||||
clock_en => clock_en,
|
||||
reset => reset,
|
||||
|
||||
irq_n => irq_n,
|
||||
nmi_n => nmi_n,
|
||||
|
||||
i_flag => p_reg(2),
|
||||
clear_b => clear_b,
|
||||
|
||||
vect_bit => vect_bit,
|
||||
interrupt => interrupt,
|
||||
vect_addr => vect_addr );
|
||||
|
||||
read_write_n <= rwn;
|
||||
addr_out(16) <= a16;
|
||||
sync_out <= sync;
|
||||
end structural;
|
||||
83
Commodore - 64_MiST/rtl/c1541/cpu/proc_interrupt.vhd
Normal file
83
Commodore - 64_MiST/rtl/c1541/cpu/proc_interrupt.vhd
Normal file
@@ -0,0 +1,83 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
entity proc_interrupt is
|
||||
port (
|
||||
clock : in std_logic;
|
||||
clock_en : in std_logic;
|
||||
reset : in std_logic;
|
||||
|
||||
irq_n : in std_logic;
|
||||
nmi_n : in std_logic;
|
||||
|
||||
i_flag : in std_logic;
|
||||
clear_b : out std_logic;
|
||||
|
||||
vect_bit : in std_logic;
|
||||
interrupt : out std_logic;
|
||||
vect_addr : out std_logic_vector(3 downto 0) );
|
||||
|
||||
end proc_interrupt;
|
||||
|
||||
architecture gideon of proc_interrupt is
|
||||
signal irq_c : std_logic := '0';
|
||||
signal nmi_c : std_logic := '0';
|
||||
signal nmi_d : std_logic := '0';
|
||||
signal nmi_act : std_logic := '0';
|
||||
signal vect_h : std_logic_vector(1 downto 0) := "00";
|
||||
type state_t is (idle, do_irq, do_nmi);
|
||||
signal state : state_t;
|
||||
begin
|
||||
vect_addr <= '1' & vect_h & vect_bit;
|
||||
interrupt <= irq_c or nmi_act;
|
||||
|
||||
process(clock)
|
||||
begin
|
||||
if rising_edge(clock) then
|
||||
irq_c <= not (irq_n or i_flag);
|
||||
nmi_c <= not nmi_n;
|
||||
clear_b <= '0';
|
||||
|
||||
if clock_en='1' then
|
||||
nmi_d <= nmi_c;
|
||||
if nmi_d = '0' and nmi_c = '1' then -- edge
|
||||
nmi_act <= '1';
|
||||
end if;
|
||||
|
||||
case state is
|
||||
when idle =>
|
||||
vect_h <= "11"; -- FE/FF
|
||||
if nmi_act = '1' then
|
||||
vect_h <= "01"; -- FA/FB
|
||||
state <= do_nmi;
|
||||
elsif irq_c = '1' then
|
||||
state <= do_irq;
|
||||
clear_b <= '1';
|
||||
end if;
|
||||
|
||||
when do_irq =>
|
||||
if vect_bit='0' or irq_c='0' then
|
||||
state <= idle;
|
||||
end if;
|
||||
|
||||
when do_nmi =>
|
||||
if vect_bit='0' then
|
||||
nmi_act <= '0';
|
||||
state <= idle;
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
state <= idle;
|
||||
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if reset='1' then
|
||||
vect_h <= "10"; -- FC/FD 1100
|
||||
state <= do_nmi;
|
||||
nmi_act <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end gideon;
|
||||
303
Commodore - 64_MiST/rtl/c1541/cpu/proc_registers.vhd
Normal file
303
Commodore - 64_MiST/rtl/c1541/cpu/proc_registers.vhd
Normal file
@@ -0,0 +1,303 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
use ieee.std_logic_arith.all;
|
||||
|
||||
library work;
|
||||
use work.pkg_6502_defs.all;
|
||||
use work.pkg_6502_decode.all;
|
||||
|
||||
entity proc_registers is
|
||||
generic (
|
||||
vector_page : std_logic_vector(15 downto 4) := X"FFF" );
|
||||
port (
|
||||
clock : in std_logic;
|
||||
clock_en : in std_logic;
|
||||
reset : in std_logic;
|
||||
|
||||
-- package pins
|
||||
data_in : in std_logic_vector(7 downto 0);
|
||||
data_out : out std_logic_vector(7 downto 0);
|
||||
|
||||
so_n : in std_logic := '1';
|
||||
|
||||
-- data from "data_oper"
|
||||
alu_data : in std_logic_vector(7 downto 0);
|
||||
mem_data : in std_logic_vector(7 downto 0);
|
||||
new_flags : in std_logic_vector(7 downto 0);
|
||||
|
||||
-- from implied handler
|
||||
set_a : in std_logic;
|
||||
set_x : in std_logic;
|
||||
set_y : in std_logic;
|
||||
set_s : in std_logic;
|
||||
set_data : in std_logic_vector(7 downto 0);
|
||||
|
||||
-- interrupt pins
|
||||
interrupt : in std_logic;
|
||||
vect_addr : in std_logic_vector(3 downto 0);
|
||||
set_b : in std_logic;
|
||||
clear_b : in std_logic;
|
||||
|
||||
-- from processor state machine and decoder
|
||||
sync : in std_logic; -- latch ireg
|
||||
latch_dreg : in std_logic;
|
||||
vect_bit : in std_logic;
|
||||
reg_update : in std_logic;
|
||||
copy_d2p : in std_logic;
|
||||
a_mux : in t_amux;
|
||||
dout_mux : in t_dout_mux;
|
||||
pc_oper : in t_pc_oper;
|
||||
s_oper : in t_sp_oper;
|
||||
adl_oper : in t_adl_oper;
|
||||
adh_oper : in t_adh_oper;
|
||||
|
||||
-- outputs to processor state machine
|
||||
i_reg : out std_logic_vector(7 downto 0) := X"00";
|
||||
index_carry : out std_logic;
|
||||
pc_carry : out std_logic;
|
||||
branch_taken : out boolean;
|
||||
|
||||
-- register outputs
|
||||
addr_out : out std_logic_vector(15 downto 0) := X"FFFF";
|
||||
|
||||
d_reg : out std_logic_vector(7 downto 0) := X"00";
|
||||
a_reg : out std_logic_vector(7 downto 0) := X"00";
|
||||
x_reg : out std_logic_vector(7 downto 0) := X"00";
|
||||
y_reg : out std_logic_vector(7 downto 0) := X"00";
|
||||
s_reg : out std_logic_vector(7 downto 0) := X"00";
|
||||
p_reg : out std_logic_vector(7 downto 0) := X"00";
|
||||
pc_out : out std_logic_vector(15 downto 0) );
|
||||
end proc_registers;
|
||||
|
||||
architecture gideon of proc_registers is
|
||||
-- signal a_reg : std_logic_vector(7 downto 0);
|
||||
signal dreg : std_logic_vector(7 downto 0) := X"00";
|
||||
signal a_reg_i : std_logic_vector(7 downto 0) := X"00";
|
||||
signal x_reg_i : std_logic_vector(7 downto 0) := X"00";
|
||||
signal y_reg_i : std_logic_vector(7 downto 0) := X"00";
|
||||
signal selected_idx : std_logic_vector(7 downto 0) := X"00";
|
||||
signal i_reg_i : std_logic_vector(7 downto 0) := X"00";
|
||||
signal s_reg_i : std_logic_vector(7 downto 0) := X"00";
|
||||
signal p_reg_i : std_logic_vector(7 downto 0) := X"30";
|
||||
signal pcl, pch : std_logic_vector(7 downto 0) := X"FF";
|
||||
signal adl, adh : std_logic_vector(7 downto 0) := X"00";
|
||||
signal pc_carry_i : std_logic;
|
||||
signal pc_carry_d : std_logic;
|
||||
signal branch_flag : std_logic;
|
||||
signal reg_out : std_logic_vector(7 downto 0);
|
||||
signal vect : std_logic_vector(3 downto 0) := "1111";
|
||||
signal dreg_zero : std_logic;
|
||||
|
||||
alias C_flag : std_logic is p_reg_i(0);
|
||||
alias Z_flag : std_logic is p_reg_i(1);
|
||||
alias I_flag : std_logic is p_reg_i(2);
|
||||
alias D_flag : std_logic is p_reg_i(3);
|
||||
alias B_flag : std_logic is p_reg_i(4);
|
||||
alias V_flag : std_logic is p_reg_i(6);
|
||||
alias N_flag : std_logic is p_reg_i(7);
|
||||
|
||||
begin
|
||||
dreg_zero <= '1' when dreg=X"00" else '0';
|
||||
|
||||
process(clock)
|
||||
variable pcl_t : std_logic_vector(8 downto 0);
|
||||
variable adl_t : std_logic_vector(8 downto 0);
|
||||
begin
|
||||
if rising_edge(clock) then
|
||||
if clock_en='1' then
|
||||
-- Data Register
|
||||
if latch_dreg='1' then
|
||||
dreg <= data_in;
|
||||
end if;
|
||||
|
||||
-- Flags Register
|
||||
if copy_d2p = '1' then
|
||||
p_reg_i <= dreg;
|
||||
elsif reg_update='1' then
|
||||
p_reg_i <= new_flags;
|
||||
end if;
|
||||
|
||||
if vect_bit='0' then
|
||||
I_flag <= '1';
|
||||
end if;
|
||||
|
||||
if set_b='1' then
|
||||
B_flag <= '1';
|
||||
elsif clear_b='1' then
|
||||
B_flag <= '0';
|
||||
end if;
|
||||
|
||||
if so_n='0' then -- only 1 bit is affected, so no syncronization needed
|
||||
V_flag <= '1';
|
||||
end if;
|
||||
|
||||
-- Instruction Register
|
||||
if sync='1' then
|
||||
i_reg_i <= data_in;
|
||||
|
||||
-- Fix for PLA only :(
|
||||
if load_a(i_reg_i) then
|
||||
a_reg_i <= dreg;
|
||||
N_flag <= dreg(7);
|
||||
Z_flag <= dreg_zero;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Logic for the Program Counter
|
||||
pc_carry_i <= '0';
|
||||
case pc_oper is
|
||||
when increment =>
|
||||
if pcl = X"FF" then
|
||||
pch <= pch + 1;
|
||||
end if;
|
||||
pcl <= pcl + 1;
|
||||
|
||||
when copy =>
|
||||
pcl <= dreg;
|
||||
pch <= data_in;
|
||||
|
||||
when from_alu =>
|
||||
pcl_t := ('0' & pcl) + (dreg(7) & dreg); -- sign extended 1 bit
|
||||
pcl <= pcl_t(7 downto 0);
|
||||
pc_carry_i <= pcl_t(8);
|
||||
pc_carry_d <= dreg(7);
|
||||
|
||||
when others => -- keep (and fix)
|
||||
if pc_carry_i='1' then
|
||||
if pc_carry_d='1' then
|
||||
pch <= pch - 1;
|
||||
else
|
||||
pch <= pch + 1;
|
||||
end if;
|
||||
end if;
|
||||
end case;
|
||||
|
||||
-- Logic for the Address register
|
||||
case adl_oper is
|
||||
when increment =>
|
||||
adl <= adl + 1;
|
||||
|
||||
when add_idx =>
|
||||
adl_t := ('0' & dreg) + ('0' & selected_idx);
|
||||
adl <= adl_t(7 downto 0);
|
||||
index_carry <= adl_t(8);
|
||||
|
||||
when load_bus =>
|
||||
adl <= data_in;
|
||||
|
||||
when copy_dreg =>
|
||||
adl <= dreg;
|
||||
|
||||
when others =>
|
||||
null;
|
||||
|
||||
end case;
|
||||
|
||||
case adh_oper is
|
||||
when increment =>
|
||||
adh <= adh + 1;
|
||||
|
||||
when clear =>
|
||||
adh <= (others => '0');
|
||||
|
||||
when load_bus =>
|
||||
adh <= data_in;
|
||||
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
|
||||
-- Logic for ALU register
|
||||
if reg_update='1' then
|
||||
if set_a='1' then
|
||||
a_reg_i <= set_data;
|
||||
elsif store_a_from_alu(i_reg_i) then
|
||||
a_reg_i <= alu_data;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Logic for Index registers
|
||||
if reg_update='1' then
|
||||
if set_x='1' then
|
||||
x_reg_i <= set_data;
|
||||
elsif load_x(i_reg_i) then
|
||||
x_reg_i <= alu_data; --dreg; -- alu is okay, too (they should be the same)
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if reg_update='1' then
|
||||
if set_y='1' then
|
||||
y_reg_i <= set_data;
|
||||
elsif load_y(i_reg_i) then
|
||||
y_reg_i <= dreg;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Logic for the Stack Pointer
|
||||
if set_s='1' then
|
||||
s_reg_i <= set_data;
|
||||
else
|
||||
case s_oper is
|
||||
when increment =>
|
||||
s_reg_i <= s_reg_i + 1;
|
||||
|
||||
when decrement =>
|
||||
s_reg_i <= s_reg_i - 1;
|
||||
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
-- Reset
|
||||
if reset='1' then
|
||||
p_reg_i <= X"34"; -- I=1
|
||||
index_carry <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
with i_reg_i(7 downto 6) select branch_flag <=
|
||||
N_flag when "00",
|
||||
V_flag when "01",
|
||||
C_flag when "10",
|
||||
Z_flag when "11",
|
||||
'0' when others;
|
||||
|
||||
branch_taken <= (branch_flag xor not i_reg_i(5))='1';
|
||||
|
||||
with a_mux select addr_out <=
|
||||
vector_page & vect_addr when 0,
|
||||
adh & adl when 1,
|
||||
X"01" & s_reg_i when 2,
|
||||
pch & pcl when 3;
|
||||
|
||||
with i_reg_i(1 downto 0) select reg_out <=
|
||||
y_reg_i when "00",
|
||||
a_reg_i when "01",
|
||||
x_reg_i when "10",
|
||||
a_reg_i and x_reg_i when others;
|
||||
|
||||
with dout_mux select data_out <=
|
||||
dreg when reg_d,
|
||||
a_reg_i when reg_accu,
|
||||
reg_out when reg_axy,
|
||||
p_reg_i or X"20" when reg_flags,
|
||||
pcl when reg_pcl,
|
||||
pch when reg_pch,
|
||||
mem_data when shift_res,
|
||||
X"FF" when others;
|
||||
|
||||
selected_idx <= y_reg_i when select_index_y(i_reg_i) else x_reg_i;
|
||||
|
||||
pc_carry <= pc_carry_i;
|
||||
s_reg <= s_reg_i;
|
||||
p_reg <= p_reg_i;
|
||||
i_reg <= i_reg_i;
|
||||
a_reg <= a_reg_i;
|
||||
x_reg <= x_reg_i;
|
||||
y_reg <= y_reg_i;
|
||||
d_reg <= dreg;
|
||||
pc_out <= pch & pcl;
|
||||
end gideon;
|
||||
60
Commodore - 64_MiST/rtl/c1541/cpu/shifter.vhd
Normal file
60
Commodore - 64_MiST/rtl/c1541/cpu/shifter.vhd
Normal file
@@ -0,0 +1,60 @@
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity shifter is
|
||||
port (
|
||||
operation : in std_logic_vector(2 downto 0);
|
||||
enable : in std_logic := '1'; -- instruction(1)
|
||||
|
||||
c_in : in std_logic;
|
||||
n_in : in std_logic;
|
||||
z_in : in std_logic;
|
||||
|
||||
data_in : in std_logic_vector(7 downto 0);
|
||||
|
||||
c_out : out std_logic;
|
||||
n_out : out std_logic;
|
||||
z_out : out std_logic;
|
||||
|
||||
data_out : out std_logic_vector(7 downto 0) := X"00");
|
||||
|
||||
end shifter;
|
||||
|
||||
architecture gideon of shifter is
|
||||
signal data_out_i : std_logic_vector(7 downto 0) := X"00";
|
||||
signal zero : std_logic := '0';
|
||||
signal oper4 : std_logic_vector(3 downto 0) := X"0";
|
||||
begin
|
||||
-- ASL $nn ROL $nn LSR $nn ROR $nn STX $nn LDX $nn DEC $nn INC $nn
|
||||
|
||||
with operation select data_out_i <=
|
||||
data_in(6 downto 0) & '0' when "000",
|
||||
data_in(6 downto 0) & c_in when "001",
|
||||
'0' & data_in(7 downto 1) when "010",
|
||||
c_in & data_in(7 downto 1) when "011",
|
||||
data_in - 1 when "110",
|
||||
data_in + 1 when "111",
|
||||
data_in when others;
|
||||
|
||||
zero <= '1' when data_out_i = X"00" else '0';
|
||||
|
||||
oper4 <= enable & operation;
|
||||
|
||||
with oper4 select c_out <=
|
||||
data_in(7) when "1000" | "1001",
|
||||
data_in(0) when "1010" | "1011",
|
||||
c_in when others;
|
||||
|
||||
with oper4 select z_out <=
|
||||
zero when "1000" | "1001" | "1010" | "1011" | "1101" | "1110" | "1111",
|
||||
z_in when others;
|
||||
|
||||
with oper4 select n_out <=
|
||||
data_out_i(7) when "1000" | "1001" | "1010" | "1011" | "1101" | "1110" | "1111",
|
||||
n_in when others;
|
||||
|
||||
data_out <= data_out_i when enable='1' else data_in;
|
||||
|
||||
end gideon;
|
||||
316
Commodore - 64_MiST/rtl/c1541/gcr_floppy.vhd
Normal file
316
Commodore - 64_MiST/rtl/c1541/gcr_floppy.vhd
Normal file
@@ -0,0 +1,316 @@
|
||||
---------------------------------------------------------------------------------
|
||||
-- Commodore 1541 gcr floppy (read/write) by Dar (darfpga@aol.fr) 23-May-2017
|
||||
-- http://darfpga.blogspot.fr
|
||||
--
|
||||
-- produces GCR data, byte(ready) and sync signal to feed c1541_logic from current
|
||||
-- track buffer ram which contains D64 data
|
||||
--
|
||||
-- gets GCR data from c1541_logic, while producing byte(ready) signal. Data feed
|
||||
-- track buffer ram after conversion
|
||||
--
|
||||
-- Input clk 32MHz
|
||||
--
|
||||
---------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity gcr_floppy is
|
||||
port(
|
||||
clk32 : in std_logic;
|
||||
dout : out std_logic_vector(7 downto 0); -- data from ram to 1541 logic
|
||||
din : in std_logic_vector(7 downto 0); -- data from 1541 logic to ram
|
||||
mode : in std_logic; -- read/write
|
||||
mtr : in std_logic; -- stepper motor on/off
|
||||
sync_n : out std_logic; -- reading SYNC bytes
|
||||
byte_n : out std_logic; -- byte ready
|
||||
|
||||
track : in std_logic_vector(5 downto 0);
|
||||
sector : out std_logic_vector(4 downto 0);
|
||||
byte_addr : out std_logic_vector(7 downto 0);
|
||||
|
||||
ram_do : in std_logic_vector(7 downto 0);
|
||||
ram_di : buffer std_logic_vector(7 downto 0);
|
||||
ram_we : out std_logic;
|
||||
ram_ready : in std_logic
|
||||
);
|
||||
end gcr_floppy;
|
||||
|
||||
architecture struct of gcr_floppy is
|
||||
|
||||
signal bit_clk_en : std_logic;
|
||||
signal sync_cnt : std_logic_vector(5 downto 0) := (others => '0');
|
||||
signal byte_cnt : std_logic_vector(8 downto 0) := (others => '0');
|
||||
signal nibble : std_logic := '0';
|
||||
signal gcr_bit_cnt : std_logic_vector(3 downto 0) := (others => '0');
|
||||
signal bit_cnt : std_logic_vector(2 downto 0) := (others => '0');
|
||||
|
||||
signal sync_in_n : std_logic;
|
||||
signal byte_in_n : std_logic;
|
||||
|
||||
signal sector_dbl : std_logic_vector(4 downto 0) := (others => '0');
|
||||
signal state : std_logic := '0';
|
||||
|
||||
signal data_header : std_logic_vector(7 downto 0);
|
||||
signal data_body : std_logic_vector(7 downto 0);
|
||||
signal data : std_logic_vector(7 downto 0);
|
||||
signal data_cks : std_logic_vector(7 downto 0);
|
||||
signal gcr_nibble : std_logic_vector(4 downto 0);
|
||||
signal gcr_bit : std_logic;
|
||||
signal gcr_byte : std_logic_vector(7 downto 0);
|
||||
|
||||
signal mode_r1 : std_logic;
|
||||
signal mode_r2 : std_logic;
|
||||
|
||||
type gcr_array is array(0 to 15) of std_logic_vector(4 downto 0);
|
||||
|
||||
signal gcr_lut : gcr_array :=
|
||||
("01010","11010","01001","11001",
|
||||
"01110","11110","01101","11101",
|
||||
"10010","10011","01011","11011",
|
||||
"10110","10111","01111","10101");
|
||||
|
||||
signal sector_max : std_logic_vector(4 downto 0);
|
||||
|
||||
signal gcr_byte_out : std_logic_vector(7 downto 0);
|
||||
signal gcr_bit_out : std_logic;
|
||||
signal gcr_nibble_out : std_logic_vector(4 downto 0);
|
||||
signal nibble_out : std_logic_vector(3 downto 0);
|
||||
|
||||
signal autorise_write : std_logic;
|
||||
signal autorise_count : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
sync_n <= sync_in_n when mtr = '1' and ram_ready = '1' else '1';
|
||||
|
||||
sector <= sector_dbl;
|
||||
|
||||
with byte_cnt select
|
||||
data_header <=
|
||||
X"08" when "000000000",
|
||||
"00"&track xor "000"§or_dbl when "000000001",
|
||||
"000"§or_dbl when "000000010",
|
||||
"00"&track when "000000011",
|
||||
X"20" when "000000100",
|
||||
X"20" when "000000101",
|
||||
X"0F" when others;
|
||||
|
||||
with byte_cnt select
|
||||
data_body <=
|
||||
X"07" when "000000000",
|
||||
data_cks when "100000001",
|
||||
X"00" when "100000010",
|
||||
X"00" when "100000011",
|
||||
X"0F" when "100000100",
|
||||
X"0F" when "100000101",
|
||||
X"0F" when "100000110",
|
||||
X"0F" when "100000111",
|
||||
X"0F" when "100001000",
|
||||
X"0F" when "100001001",
|
||||
X"0F" when "100001010",
|
||||
X"0F" when "100001011",
|
||||
X"0F" when "100001100",
|
||||
X"0F" when "100001101",
|
||||
X"0F" when "100001110",
|
||||
X"0F" when "100001111",
|
||||
X"0F" when "100010000",
|
||||
X"0F" when "100010001",
|
||||
ram_do when others;
|
||||
|
||||
with state select
|
||||
data <= data_header when '0', data_body when others;
|
||||
|
||||
with nibble select
|
||||
gcr_nibble <=
|
||||
gcr_lut(to_integer(unsigned(data(7 downto 4)))) when '0',
|
||||
gcr_lut(to_integer(unsigned(data(3 downto 0)))) when others;
|
||||
|
||||
gcr_bit <= gcr_nibble(to_integer(unsigned(gcr_bit_cnt)));
|
||||
|
||||
sector_max <= "10100" when track < std_logic_vector(to_unsigned(18,6)) else
|
||||
"10010" when track < std_logic_vector(to_unsigned(25,6)) else
|
||||
"10001" when track < std_logic_vector(to_unsigned(31,6)) else
|
||||
"10000" ;
|
||||
|
||||
gcr_bit_out <= gcr_byte_out(to_integer(unsigned(not bit_cnt)));
|
||||
|
||||
with gcr_nibble_out select
|
||||
nibble_out <= X"0" when "01010",--"01010",
|
||||
X"1" when "01011",--"11010",
|
||||
X"2" when "10010",--"01001",
|
||||
X"3" when "10011",--"11001",
|
||||
X"4" when "01110",--"01110",
|
||||
X"5" when "01111",--"11110",
|
||||
X"6" when "10110",--"01101",
|
||||
X"7" when "10111",--"11101",
|
||||
X"8" when "01001",--"10010",
|
||||
X"9" when "11001",--"10011",
|
||||
X"A" when "11010",--"01011",
|
||||
X"B" when "11011",--"11011",
|
||||
X"C" when "01101",--"10110",
|
||||
X"D" when "11101",--"10111",
|
||||
X"E" when "11110",--"01111",
|
||||
X"F" when others; --"10101",
|
||||
|
||||
process (clk32)
|
||||
variable bit_clk_cnt : std_logic_vector(7 downto 0) := (others => '0');
|
||||
begin
|
||||
if rising_edge(clk32) then
|
||||
|
||||
mode_r1 <= mode;
|
||||
|
||||
if (mode_r1 xor mode) = '1' then -- read <-> write change
|
||||
bit_clk_cnt := (others => '0');
|
||||
byte_n <= '1';
|
||||
bit_clk_en <= '0';
|
||||
else
|
||||
bit_clk_en <= '0';
|
||||
if bit_clk_cnt = X"6F" then
|
||||
bit_clk_en <= '1';
|
||||
bit_clk_cnt := (others => '0');
|
||||
else
|
||||
bit_clk_cnt := bit_clk_cnt + '1';
|
||||
end if;
|
||||
|
||||
byte_n <= '1';
|
||||
if byte_in_n = '0' and mtr = '1' and ram_ready = '1' then
|
||||
if bit_clk_cnt > X"10" then
|
||||
if bit_clk_cnt < X"5E" then
|
||||
byte_n <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process;
|
||||
|
||||
read_write_process : process (clk32, bit_clk_en)
|
||||
begin
|
||||
if rising_edge(clk32) then
|
||||
|
||||
ram_we <= '0';
|
||||
if bit_clk_en = '1' then
|
||||
mode_r2 <= mode;
|
||||
if mode = '1' then autorise_write <= '0'; end if;
|
||||
|
||||
if (mode xor mode_r2) = '1' then
|
||||
if mode = '1' then -- leaving write mode
|
||||
sync_in_n <= '0';
|
||||
sync_cnt <= (others => '0');
|
||||
state <= '0';
|
||||
else -- entering write mode
|
||||
byte_cnt <= (others => '0');
|
||||
nibble <= '0';
|
||||
gcr_bit_cnt <= (others => '0');
|
||||
bit_cnt <= (others => '0');
|
||||
gcr_byte <= (others => '0');
|
||||
data_cks <= (others => '0');
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if sync_in_n = '0' and mode = '1' then
|
||||
|
||||
byte_cnt <= (others => '0');
|
||||
nibble <= '0';
|
||||
gcr_bit_cnt <= (others => '0');
|
||||
bit_cnt <= (others => '0');
|
||||
dout <= (others => '0');
|
||||
gcr_byte <= (others => '0');
|
||||
data_cks <= (others => '0');
|
||||
|
||||
if sync_cnt = X"31" then
|
||||
sync_cnt <= (others => '0');
|
||||
sync_in_n <= '1';
|
||||
else
|
||||
sync_cnt <= sync_cnt + '1';
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
if sync_in_n = '1' or mode = '0' then
|
||||
|
||||
gcr_bit_cnt <= gcr_bit_cnt + '1';
|
||||
if gcr_bit_cnt = X"4" then
|
||||
gcr_bit_cnt <= (others => '0');
|
||||
if nibble = '1' then
|
||||
nibble <= '0';
|
||||
byte_addr <= byte_cnt(7 downto 0);
|
||||
if byte_cnt = "000000000" then
|
||||
data_cks <= (others => '0');
|
||||
else
|
||||
data_cks <= data_cks xor data;
|
||||
end if;
|
||||
if mode = '1' or (mode = '0' and autorise_count = '1') then
|
||||
byte_cnt <= byte_cnt + '1';
|
||||
end if;
|
||||
else
|
||||
nibble <= '1';
|
||||
if mode = '0' and ram_di = X"07" then
|
||||
autorise_write <= '1';
|
||||
autorise_count <= '1';
|
||||
end if;
|
||||
if byte_cnt >= "100000000" then
|
||||
autorise_write <= '0';
|
||||
autorise_count <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
bit_cnt <= bit_cnt + '1';
|
||||
byte_in_n <= '1';
|
||||
if bit_cnt = X"7" then
|
||||
byte_in_n <= '0';
|
||||
gcr_byte_out <= din;
|
||||
end if;
|
||||
|
||||
if state = '0' then
|
||||
if byte_cnt = "000010000" then
|
||||
sync_in_n <= '0';
|
||||
state<= '1';
|
||||
end if;
|
||||
else
|
||||
if byte_cnt = "100010001" then
|
||||
sync_in_n <= '0';
|
||||
state <= '0';
|
||||
if sector_dbl = sector_max then
|
||||
sector_dbl <= (others=>'0');
|
||||
else
|
||||
sector_dbl <= sector_dbl + '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- demux byte from floppy (ram)
|
||||
gcr_byte <= gcr_byte(6 downto 0) & gcr_bit;
|
||||
|
||||
if bit_cnt = X"7" then
|
||||
dout <= gcr_byte(6 downto 0) & gcr_bit;
|
||||
end if;
|
||||
|
||||
-- serialise/convert byte to floppy (ram)
|
||||
gcr_nibble_out <= gcr_nibble_out(3 downto 0) & gcr_bit_out;
|
||||
|
||||
if gcr_bit_cnt = X"0" then
|
||||
if nibble = '0' then
|
||||
ram_di(3 downto 0) <= nibble_out;
|
||||
else
|
||||
ram_di(7 downto 4) <= nibble_out;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if gcr_bit_cnt = X"1" and nibble = '0' then
|
||||
if autorise_write = '1' then
|
||||
ram_we <= '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end struct;
|
||||
@@ -121,23 +121,20 @@ component sram is port
|
||||
);
|
||||
end component;
|
||||
|
||||
---------
|
||||
-- Mist IO
|
||||
---------
|
||||
|
||||
-- config string used by the io controller to fill the OSD
|
||||
--constant CONF_STR : string := "C64;PRG;S1,D64;O2,Video standard,PAL,NTSC;O8A,Scandoubler Fx,None,HQ2x-320,HQ2x-160,CRT 25%,CRT 50%;O3,Joysticks,normal,swapped;O6,Audio filter,On,Off;T5,Reset;V0,v0.27.33";
|
||||
constant CONF_STR : string := "C64;;"&
|
||||
"S,D64,Mount Disk;"&
|
||||
"F,PRG,Load File;"&
|
||||
"F,CRT,Load Cartridge;" &
|
||||
"O2,Video standard,PAL,NTSC;"&
|
||||
"O8A,Scandoubler Fx,None,HQ2x-320,HQ2x-160,CRT 25%,CRT 50%;"&
|
||||
"O3,Joysticks,normal,swapped;"&
|
||||
"O6,Audio filter,On,Off;"&
|
||||
--"OB,BIOS,C64,C64GS;" &
|
||||
--"T5,Reset;"&
|
||||
"V0,v0.30.30";
|
||||
constant CONF_STR : string :=
|
||||
"C64;;"&
|
||||
"S,D64,Mount Disk;"&
|
||||
"F,PRG,Load File;"&
|
||||
"F,CRT,Load Cartridge;" &--3
|
||||
-- "F,TAP,Load File;"&--4
|
||||
-- "F,T64,Load File;"&--5
|
||||
"O2,Video standard,PAL,NTSC;"&
|
||||
"O8A,Scandoubler Fx,None,HQ2x-320,HQ2x-160,CRT 25%,CRT 50%;"&
|
||||
"O3,Joysticks,normal,swapped;"&
|
||||
"O6,Audio filter,On,Off;"&
|
||||
-- "OB,BIOS,C64,C64GS;" &
|
||||
"T5,Reset & Detach Cartridge;"&
|
||||
"V0,v0.35.00";
|
||||
|
||||
-- convert string to std_logic_vector to be given to user_io
|
||||
function to_slv(s: string) return std_logic_vector is
|
||||
@@ -278,14 +275,15 @@ end component;
|
||||
|
||||
---------
|
||||
-- audio
|
||||
---------
|
||||
--------
|
||||
|
||||
component sigma_delta_dac port
|
||||
(
|
||||
CLK : in std_logic;
|
||||
RESET : in std_logic;
|
||||
DACin : in std_logic_vector(14 downto 0);
|
||||
DACout : out std_logic
|
||||
clk : in std_logic;
|
||||
ldatasum : in std_logic_vector(14 downto 0);
|
||||
rdatasum : in std_logic_vector(14 downto 0);
|
||||
aleft : out std_logic;
|
||||
aright : out std_logic
|
||||
);
|
||||
|
||||
end component sigma_delta_dac;
|
||||
@@ -431,7 +429,6 @@ end component cartridge;
|
||||
signal sd_change : std_logic;
|
||||
signal disk_readonly : std_logic;
|
||||
signal old_download : std_logic;
|
||||
-- these need to be redirected to the SDRAM
|
||||
signal sdram_we : std_logic;
|
||||
signal sdram_ce : std_logic;
|
||||
|
||||
@@ -483,7 +480,7 @@ end component cartridge;
|
||||
signal hsync_out : std_logic;
|
||||
signal vsync_out : std_logic;
|
||||
|
||||
signal audio_data : std_logic_vector(17 downto 0);
|
||||
signal audio_data : std_logic_vector(15 downto 0);
|
||||
|
||||
signal reset_counter : integer;
|
||||
signal reset_n : std_logic;
|
||||
@@ -492,7 +489,6 @@ end component cartridge;
|
||||
signal nmi : std_logic;
|
||||
signal nmi_ack : std_logic;
|
||||
signal erasing : std_logic;
|
||||
-- temporary signal to extend c64_addr to 24bit LCA
|
||||
signal c64_addr_temp : std_logic_vector(24 downto 0);
|
||||
signal cart_blk_len : std_logic_vector(31 downto 0);
|
||||
signal cart_hdr_cnt : std_logic_vector(3 downto 0);
|
||||
@@ -503,7 +499,7 @@ end component cartridge;
|
||||
begin
|
||||
|
||||
-- 1541 activity led
|
||||
LED <= not led_disk;
|
||||
LED <= not ioctl_download;
|
||||
|
||||
iec_cycle <= '1' when ces = "1011" else '0';
|
||||
|
||||
@@ -638,7 +634,7 @@ begin
|
||||
end if;
|
||||
|
||||
if ioctl_wr='1' then
|
||||
if ioctl_index = 2 then
|
||||
if ioctl_index = 2 then--prg
|
||||
if ioctl_addr = 0 then
|
||||
ioctl_load_addr(7 downto 0) <= ioctl_data;
|
||||
elsif(ioctl_addr = 1) then
|
||||
@@ -688,6 +684,15 @@ begin
|
||||
ioctl_ram_wr <= '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if ioctl_index = 4 then
|
||||
if ioctl_addr = 0 then
|
||||
ioctl_load_addr <= '0' & X"200000";
|
||||
ioctl_ram_data <= ioctl_data;
|
||||
else
|
||||
ioctl_ram_wr <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
@@ -806,29 +811,21 @@ begin
|
||||
ce => sdram_ce
|
||||
);
|
||||
|
||||
dac : sigma_delta_dac
|
||||
port map (
|
||||
clk => clk32,
|
||||
ldatasum => audio_data(15 downto 1),
|
||||
rdatasum => audio_data(15 downto 1),
|
||||
aleft => AUDIO_L,
|
||||
aright => AUDIO_R
|
||||
);
|
||||
|
||||
-- decode audio
|
||||
dac_l : sigma_delta_dac
|
||||
port map (
|
||||
CLK => clk32,
|
||||
DACin => not audio_data(17) & audio_data(16 downto 3),
|
||||
DACout => AUDIO_L,
|
||||
RESET => '0'
|
||||
);
|
||||
|
||||
dac_r : sigma_delta_dac
|
||||
port map (
|
||||
CLK => clk32,
|
||||
DACin => not audio_data(17) & audio_data(16 downto 3),
|
||||
DACout => AUDIO_R,
|
||||
RESET => '0'
|
||||
);
|
||||
|
||||
fpga64 : entity work.fpga64_sid_iec
|
||||
port map(
|
||||
clk32 => clk32,
|
||||
reset_n => reset_n,
|
||||
c64gs => status(11),
|
||||
c64gs => status(11),-- not enough BRAM
|
||||
kbd_clk => not ps2_clk,
|
||||
kbd_dat => ps2_dat,
|
||||
ramAddr => c64_addr_int,
|
||||
@@ -873,12 +870,12 @@ begin
|
||||
iec_clk_o => c64_iec_clk_o,
|
||||
iec_data_i => not c64_iec_data_i,
|
||||
iec_clk_i => not c64_iec_clk_i,
|
||||
iec_atn_i => not c64_iec_atn_i,
|
||||
-- iec_atn_i => not c64_iec_atn_i,
|
||||
disk_num => open,
|
||||
c64rom_addr => ioctl_addr(13 downto 0),
|
||||
c64rom_data => ioctl_data,
|
||||
c64rom_wr => c64rom_wr,
|
||||
cart_detach_key => cart_detach_key,
|
||||
-- cart_detach_key => cart_detach_key,
|
||||
reset_key => reset_key
|
||||
);
|
||||
|
||||
|
||||
@@ -141,7 +141,8 @@ begin
|
||||
rdaddress => std_logic_vector(cpuAddr(14) & cpuAddr(12 downto 0)),
|
||||
q => romData_c64
|
||||
);
|
||||
|
||||
|
||||
-- not enough BRAM on MIST FPGA
|
||||
-- kernelromGS: entity work.rom_GS64
|
||||
-- port map
|
||||
-- (
|
||||
@@ -157,6 +158,7 @@ begin
|
||||
|
||||
|
||||
romData <= romData_c64gs when c64gs_ena = '1' else romData_c64;
|
||||
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
|
||||
@@ -91,9 +91,9 @@ entity fpga64_sid_iec is
|
||||
ces : out std_logic_vector(3 downto 0);
|
||||
|
||||
--Connector to the SID
|
||||
SIDclk : out std_logic;
|
||||
SIDclk : buffer std_logic;
|
||||
still : out unsigned(15 downto 0);
|
||||
audio_data : out std_logic_vector(17 downto 0);
|
||||
audio_data : out std_logic_vector(15 downto 0);
|
||||
extfilter_en: in std_logic;
|
||||
|
||||
-- IEC
|
||||
@@ -102,7 +102,7 @@ entity fpga64_sid_iec is
|
||||
iec_clk_o : out std_logic;
|
||||
iec_clk_i : in std_logic;
|
||||
iec_atn_o : out std_logic;
|
||||
iec_atn_i : in std_logic;
|
||||
-- iec_atn_i : in std_logic;
|
||||
|
||||
disk_num : out std_logic_vector(7 downto 0);
|
||||
|
||||
@@ -212,6 +212,10 @@ architecture rtl of fpga64_sid_iec is
|
||||
signal cpuDi: unsigned(7 downto 0);
|
||||
signal cpuDo: unsigned(7 downto 0);
|
||||
signal cpuIO: unsigned(7 downto 0);
|
||||
|
||||
signal ioF_ext: std_logic;
|
||||
signal ioE_ext: std_logic;
|
||||
signal io_data: unsigned(7 downto 0);
|
||||
|
||||
signal vicDi: unsigned(7 downto 0);
|
||||
signal vicAddr: unsigned(15 downto 0);
|
||||
@@ -246,9 +250,28 @@ architecture rtl of fpga64_sid_iec is
|
||||
signal ntscMode : std_logic;
|
||||
signal ntscModeInvert : std_logic := '0' ;
|
||||
signal restore_key : std_logic;
|
||||
|
||||
|
||||
signal clk_1MHz : std_logic_vector(31 downto 0);
|
||||
signal voice_volume : signed(17 downto 0);
|
||||
signal pot_x : std_logic_vector(7 downto 0);
|
||||
signal pot_y : std_logic_vector(7 downto 0);
|
||||
|
||||
component sid8580
|
||||
port (
|
||||
reset : in std_logic;
|
||||
clk : in std_logic;
|
||||
ce_1m : in std_logic;
|
||||
we : in std_logic;
|
||||
addr : in std_logic_vector(4 downto 0);
|
||||
data_in : in std_logic_vector(7 downto 0);
|
||||
data_out : out std_logic_vector(7 downto 0);
|
||||
pot_x : in std_logic_vector(7 downto 0);
|
||||
pot_y : in std_logic_vector(7 downto 0);
|
||||
audio_data : out std_logic_vector(15 downto 0);
|
||||
extfilter_en : in std_logic
|
||||
);
|
||||
end component sid8580;
|
||||
|
||||
begin
|
||||
-- -----------------------------------------------------------------------
|
||||
-- Local signal to outside world
|
||||
@@ -402,6 +425,9 @@ begin
|
||||
max_ram => max_ram,
|
||||
|
||||
ramData => ramDataReg,
|
||||
-- ioF_ext => ioF_ext,
|
||||
-- ioE_ext => ioE_ext,
|
||||
-- io_data => io_data,
|
||||
|
||||
cpuWe => cpuWe,
|
||||
cpuAddr => cpuAddr,
|
||||
@@ -523,7 +549,7 @@ begin
|
||||
-- -----------------------------------------------------------------------
|
||||
-- SID
|
||||
-- -----------------------------------------------------------------------
|
||||
div1m: process(clk32) -- this process devides 32 MHz to 1MHz (for the SID)
|
||||
div1m: process(clk32) -- this process devides 32 MHz to 1MHz (for the SID)
|
||||
begin
|
||||
if (rising_edge(clk32)) then
|
||||
if (reset = '1') then
|
||||
@@ -535,30 +561,23 @@ begin
|
||||
end if;
|
||||
end process;
|
||||
|
||||
audio_data <= std_logic_vector(voice_volume);
|
||||
|
||||
sid: entity work.sid_top
|
||||
sid_8580 : sid8580
|
||||
port map (
|
||||
clock => clk32,
|
||||
reset => reset,
|
||||
|
||||
addr => "000" & cpuAddr(4 downto 0),
|
||||
wren => pulseWrRam and phi0_cpu and cs_sid,
|
||||
wdata => std_logic_vector(cpuDo),
|
||||
rdata => sid_do,
|
||||
|
||||
potx => not std_logic((cia1_pao(7) and JoyA(5)) or (cia1_pao(6) and JoyB(5))),
|
||||
poty => not std_logic((cia1_pao(7) and JoyA(6)) or (cia1_pao(6) and JoyB(6))),
|
||||
comb_wave_l => '0',
|
||||
comb_wave_r => '0',
|
||||
|
||||
extfilter_en => extfilter_en,
|
||||
|
||||
start_iter => clk_1MHz(31),
|
||||
sample_left => voice_volume,
|
||||
sample_right => open
|
||||
clk => clk32,
|
||||
ce_1m => clk_1MHz(31),
|
||||
we => pulseWrRam and phi0_cpu and cs_sid,
|
||||
addr => std_logic_vector(cpuAddr(4 downto 0)),
|
||||
data_in => std_logic_vector(cpuDo),
|
||||
data_out => sid_do,
|
||||
pot_x => pot_x,
|
||||
pot_y => pot_y,
|
||||
audio_data => audio_data,
|
||||
extfilter_en => extfilter_en
|
||||
);
|
||||
|
||||
|
||||
pot_x <= X"FF" when ((cia1_pao(7) and JoyA(5)) or (cia1_pao(6) and JoyB(5))) = '0' else X"00";
|
||||
pot_y <= X"FF" when ((cia1_pao(7) and JoyA(6)) or (cia1_pao(6) and JoyB(6))) = '0' else X"00";
|
||||
-- -----------------------------------------------------------------------
|
||||
-- CIAs
|
||||
-- -----------------------------------------------------------------------
|
||||
|
||||
226
Commodore - 64_MiST/rtl/sid8580.sv
Normal file
226
Commodore - 64_MiST/rtl/sid8580.sv
Normal file
@@ -0,0 +1,226 @@
|
||||
|
||||
module sid8580
|
||||
(
|
||||
input reset,
|
||||
|
||||
input clk,
|
||||
input ce_1m,
|
||||
|
||||
input we,
|
||||
input [4:0] addr,
|
||||
input [7:0] data_in,
|
||||
output [ 7:0] data_out,
|
||||
|
||||
input [7:0] pot_x,
|
||||
input [7:0] pot_y,
|
||||
|
||||
input extfilter_en,
|
||||
output [15:0] audio_data
|
||||
);
|
||||
|
||||
// Internal Signals
|
||||
reg [7:0] Voice_1_Freq_lo;
|
||||
reg [7:0] Voice_1_Freq_hi;
|
||||
reg [7:0] Voice_1_Pw_lo;
|
||||
reg [3:0] Voice_1_Pw_hi;
|
||||
reg [7:0] Voice_1_Control;
|
||||
reg [7:0] Voice_1_Att_dec;
|
||||
reg [7:0] Voice_1_Sus_Rel;
|
||||
|
||||
reg [7:0] Voice_2_Freq_lo;
|
||||
reg [7:0] Voice_2_Freq_hi;
|
||||
reg [7:0] Voice_2_Pw_lo;
|
||||
reg [3:0] Voice_2_Pw_hi;
|
||||
reg [7:0] Voice_2_Control;
|
||||
reg [7:0] Voice_2_Att_dec;
|
||||
reg [7:0] Voice_2_Sus_Rel;
|
||||
|
||||
reg [7:0] Voice_3_Freq_lo;
|
||||
reg [7:0] Voice_3_Freq_hi;
|
||||
reg [7:0] Voice_3_Pw_lo;
|
||||
reg [3:0] Voice_3_Pw_hi;
|
||||
reg [7:0] Voice_3_Control;
|
||||
reg [7:0] Voice_3_Att_dec;
|
||||
reg [7:0] Voice_3_Sus_Rel;
|
||||
|
||||
reg [7:0] Filter_Fc_lo;
|
||||
reg [7:0] Filter_Fc_hi;
|
||||
reg [7:0] Filter_Res_Filt;
|
||||
reg [7:0] Filter_Mode_Vol;
|
||||
|
||||
wire [7:0] Misc_Osc3_Random;
|
||||
wire [7:0] Misc_Env3;
|
||||
|
||||
reg [7:0] do_buf;
|
||||
reg [7:0] sidrandom;
|
||||
|
||||
wire [11:0] voice_1;
|
||||
wire [11:0] voice_2;
|
||||
wire [11:0] voice_3;
|
||||
wire [17:0] voice_mixed;
|
||||
reg [17:0] voice_volume;
|
||||
|
||||
wire voice_1_PA_MSB;
|
||||
wire voice_2_PA_MSB;
|
||||
wire voice_3_PA_MSB;
|
||||
|
||||
wire [18:0] filtered_audio;
|
||||
wire [17:0] unsigned_audio;
|
||||
wire [18:0] unsigned_filt;
|
||||
|
||||
localparam DC_offset = 14'b00111111111111;
|
||||
|
||||
// Voice 1 Instantiation
|
||||
sid_voice v1
|
||||
(
|
||||
.clock(clk),
|
||||
.ce_1m(ce_1m),
|
||||
.reset(reset),
|
||||
.freq_lo(Voice_1_Freq_lo),
|
||||
.freq_hi(Voice_1_Freq_hi),
|
||||
.pw_lo(Voice_1_Pw_lo),
|
||||
.pw_hi(Voice_1_Pw_hi),
|
||||
.control(Voice_1_Control),
|
||||
.att_dec(Voice_1_Att_dec),
|
||||
.sus_rel(Voice_1_Sus_Rel),
|
||||
.osc_msb_in(voice_3_PA_MSB),
|
||||
.osc_msb_out(voice_1_PA_MSB),
|
||||
.signal_out(voice_1)
|
||||
);
|
||||
|
||||
// Voice 2 Instantiation
|
||||
sid_voice v2
|
||||
(
|
||||
.clock(clk),
|
||||
.ce_1m(ce_1m),
|
||||
.reset(reset),
|
||||
.freq_lo(Voice_2_Freq_lo),
|
||||
.freq_hi(Voice_2_Freq_hi),
|
||||
.pw_lo(Voice_2_Pw_lo),
|
||||
.pw_hi(Voice_2_Pw_hi),
|
||||
.control(Voice_2_Control),
|
||||
.att_dec(Voice_2_Att_dec),
|
||||
.sus_rel(Voice_2_Sus_Rel),
|
||||
.osc_msb_in(voice_1_PA_MSB),
|
||||
.osc_msb_out(voice_2_PA_MSB),
|
||||
.signal_out(voice_2)
|
||||
);
|
||||
|
||||
// Voice 3 Instantiation
|
||||
sid_voice v3
|
||||
(
|
||||
.clock(clk),
|
||||
.ce_1m(ce_1m),
|
||||
.reset(reset),
|
||||
.freq_lo(Voice_3_Freq_lo),
|
||||
.freq_hi(Voice_3_Freq_hi),
|
||||
.pw_lo(Voice_3_Pw_lo),
|
||||
.pw_hi(Voice_3_Pw_hi),
|
||||
.control(Voice_3_Control),
|
||||
.att_dec(Voice_3_Att_dec),
|
||||
.sus_rel(Voice_3_Sus_Rel),
|
||||
.osc_msb_in(voice_2_PA_MSB),
|
||||
.osc_msb_out(voice_3_PA_MSB),
|
||||
.signal_out(voice_3),
|
||||
.osc_out(Misc_Osc3_Random),
|
||||
.env_out(Misc_Env3)
|
||||
);
|
||||
|
||||
// Filter Instantiation
|
||||
sid_filters filters
|
||||
(
|
||||
.clk(clk),
|
||||
.rst(reset),
|
||||
.Fc_lo(Filter_Fc_lo),
|
||||
.Fc_hi(Filter_Fc_hi),
|
||||
.Res_Filt(Filter_Res_Filt),
|
||||
.Mode_Vol(Filter_Mode_Vol),
|
||||
.voice1(voice_1),
|
||||
.voice2(voice_2),
|
||||
.voice3(voice_3),
|
||||
.input_valid(ce_1m),
|
||||
.ext_in(12'hfff),
|
||||
.sound(audio_data),
|
||||
.extfilter_en(extfilter_en)
|
||||
);
|
||||
|
||||
assign data_out = do_buf;
|
||||
//assign audio_data = {1'b0, (filtered_audio[18:5] + 14'b1000000000000000)};
|
||||
//assign unsigned_filt = filtered_audio + 19'b1000000000000000000;
|
||||
//assign unsigned_audio = unsigned_filt[18:1];
|
||||
//assign audio_data = filtered_audio[18:3];// + 15'h4000;//{1'b0, unsigned_audio[17:1]};
|
||||
|
||||
always @(*) begin
|
||||
case (addr)
|
||||
5'h19: do_buf = pot_x;
|
||||
5'h1a: do_buf = pot_y;
|
||||
5'h1b: do_buf = Misc_Osc3_Random;
|
||||
5'h1c: do_buf = Misc_Env3;
|
||||
default: do_buf = 0;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// Register Decoding
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
Voice_1_Freq_lo <= 0;
|
||||
Voice_1_Freq_hi <= 0;
|
||||
Voice_1_Pw_lo <= 0;
|
||||
Voice_1_Pw_hi <= 0;
|
||||
Voice_1_Control <= 0;
|
||||
Voice_1_Att_dec <= 0;
|
||||
Voice_1_Sus_Rel <= 0;
|
||||
Voice_2_Freq_lo <= 0;
|
||||
Voice_2_Freq_hi <= 0;
|
||||
Voice_2_Pw_lo <= 0;
|
||||
Voice_2_Pw_hi <= 0;
|
||||
Voice_2_Control <= 0;
|
||||
Voice_2_Att_dec <= 0;
|
||||
Voice_2_Sus_Rel <= 0;
|
||||
Voice_3_Freq_lo <= 0;
|
||||
Voice_3_Freq_hi <= 0;
|
||||
Voice_3_Pw_lo <= 0;
|
||||
Voice_3_Pw_hi <= 0;
|
||||
Voice_3_Control <= 0;
|
||||
Voice_3_Att_dec <= 0;
|
||||
Voice_3_Sus_Rel <= 0;
|
||||
Filter_Fc_lo <= 0;
|
||||
Filter_Fc_hi <= 0;
|
||||
Filter_Res_Filt <= 0;
|
||||
Filter_Mode_Vol <= 0;
|
||||
end
|
||||
else begin
|
||||
if (we) begin
|
||||
case (addr)
|
||||
5'h00: Voice_1_Freq_lo <= data_in;
|
||||
5'h01: Voice_1_Freq_hi <= data_in;
|
||||
5'h02: Voice_1_Pw_lo <= data_in;
|
||||
5'h03: Voice_1_Pw_hi <= data_in[3:0];
|
||||
5'h04: Voice_1_Control <= data_in;
|
||||
5'h05: Voice_1_Att_dec <= data_in;
|
||||
5'h06: Voice_1_Sus_Rel <= data_in;
|
||||
5'h07: Voice_2_Freq_lo <= data_in;
|
||||
5'h08: Voice_2_Freq_hi <= data_in;
|
||||
5'h09: Voice_2_Pw_lo <= data_in;
|
||||
5'h0a: Voice_2_Pw_hi <= data_in[3:0];
|
||||
5'h0b: Voice_2_Control <= data_in;
|
||||
5'h0c: Voice_2_Att_dec <= data_in;
|
||||
5'h0d: Voice_2_Sus_Rel <= data_in;
|
||||
5'h0e: Voice_3_Freq_lo <= data_in;
|
||||
5'h0f: Voice_3_Freq_hi <= data_in;
|
||||
5'h10: Voice_3_Pw_lo <= data_in;
|
||||
5'h11: Voice_3_Pw_hi <= data_in[3:0];
|
||||
5'h12: Voice_3_Control <= data_in;
|
||||
5'h13: Voice_3_Att_dec <= data_in;
|
||||
5'h14: Voice_3_Sus_Rel <= data_in;
|
||||
5'h15: Filter_Fc_lo <= data_in;
|
||||
5'h16: Filter_Fc_hi <= data_in;
|
||||
5'h17: Filter_Res_Filt <= data_in;
|
||||
5'h18: Filter_Mode_Vol <= data_in;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
178
Commodore - 64_MiST/rtl/sid_envelope.sv
Normal file
178
Commodore - 64_MiST/rtl/sid_envelope.sv
Normal file
@@ -0,0 +1,178 @@
|
||||
|
||||
module sid_envelope
|
||||
(
|
||||
input clock,
|
||||
input ce_1m,
|
||||
|
||||
input reset,
|
||||
input gate,
|
||||
input [ 7:0] att_dec,
|
||||
input [ 7:0] sus_rel,
|
||||
|
||||
output reg [7:0] envelope
|
||||
);
|
||||
|
||||
// Internal Signals
|
||||
reg [ 1:0] state;
|
||||
reg gate_edge;
|
||||
reg [14:0] rate_counter;
|
||||
reg [14:0] rate_period;
|
||||
wire [14:0] adsrtable [0:15];
|
||||
reg [ 7:0] exponential_counter;
|
||||
reg [ 7:0] exponential_counter_period;
|
||||
reg hold_zero;
|
||||
reg envelope_pipeline;
|
||||
|
||||
`define ST_ATTACK 2'b00
|
||||
`define ST_DEC_SUS 2'b01
|
||||
`define ST_RELEASE 2'b10
|
||||
|
||||
assign adsrtable[4'h0] = 15'h007f;
|
||||
assign adsrtable[4'h1] = 15'h3000;
|
||||
assign adsrtable[4'h2] = 15'h1e00;
|
||||
assign adsrtable[4'h3] = 15'h0660;
|
||||
assign adsrtable[4'h4] = 15'h0182;
|
||||
assign adsrtable[4'h5] = 15'h5573;
|
||||
assign adsrtable[4'h6] = 15'h000e;
|
||||
assign adsrtable[4'h7] = 15'h3805;
|
||||
assign adsrtable[4'h8] = 15'h2424;
|
||||
assign adsrtable[4'h9] = 15'h2220;
|
||||
assign adsrtable[4'ha] = 15'h090c;
|
||||
assign adsrtable[4'hb] = 15'h0ecd;
|
||||
assign adsrtable[4'hc] = 15'h010e;
|
||||
assign adsrtable[4'hd] = 15'h23f7;
|
||||
assign adsrtable[4'he] = 15'h5237;
|
||||
assign adsrtable[4'hf] = 15'h64a8;
|
||||
|
||||
// State Logic
|
||||
always @(posedge clock) begin
|
||||
if (reset)
|
||||
state <= `ST_RELEASE;
|
||||
else if(ce_1m) begin
|
||||
if (gate_edge != gate)
|
||||
if (gate) state <= `ST_ATTACK;
|
||||
else state <= `ST_RELEASE;
|
||||
|
||||
if (((rate_counter == rate_period) &&
|
||||
(state == `ST_ATTACK ||
|
||||
(exponential_counter + 1'b1) == exponential_counter_period) &&
|
||||
(!hold_zero)))
|
||||
case (state)
|
||||
`ST_ATTACK: if (envelope + 1'b1 == 8'hff) state <= `ST_DEC_SUS;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// Gate Switch Detection
|
||||
always @(posedge clock) begin
|
||||
if (reset) gate_edge <= 1'b0;
|
||||
else if(ce_1m) begin
|
||||
if (gate_edge != gate) gate_edge <= gate;
|
||||
end
|
||||
end
|
||||
|
||||
// Envelope
|
||||
always @(posedge clock) begin
|
||||
if (reset)
|
||||
envelope <= 8'h00;
|
||||
else if(ce_1m) begin
|
||||
if (envelope_pipeline) envelope <= envelope - 1'b1;
|
||||
if (((rate_counter == rate_period) &&
|
||||
(state == `ST_ATTACK ||
|
||||
(exponential_counter + 1'b1) == exponential_counter_period) &&
|
||||
(!hold_zero)))
|
||||
case (state)
|
||||
`ST_ATTACK: envelope <= envelope + 1'b1;
|
||||
`ST_DEC_SUS: if (envelope != {2{sus_rel[7:4]}} && exponential_counter_period == 1) envelope <= envelope - 1'b1;
|
||||
`ST_RELEASE: if (exponential_counter_period == 1) envelope <= envelope - 1'b1;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// Envelope Pipeline
|
||||
always @(posedge clock) begin
|
||||
if (reset)
|
||||
envelope_pipeline <= 1'b0;
|
||||
else if(ce_1m) begin
|
||||
if (gate_edge != gate)
|
||||
if (gate) envelope_pipeline <= 1'b0;
|
||||
if (envelope_pipeline) envelope_pipeline <= 1'b0;
|
||||
if (((rate_counter == rate_period) &&
|
||||
(state == `ST_ATTACK ||
|
||||
(exponential_counter + 1'b1) == exponential_counter_period) &&
|
||||
(!hold_zero)))
|
||||
case (state)
|
||||
`ST_DEC_SUS: if (envelope != {2{sus_rel[7:4]}} && exponential_counter_period != 1) envelope_pipeline <= 1'b1;
|
||||
`ST_RELEASE: if(exponential_counter_period != 1) envelope_pipeline <= 1'b1;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// Exponential Counter
|
||||
always @(posedge clock) begin
|
||||
if (reset)
|
||||
exponential_counter <= 8'h00;
|
||||
else if(ce_1m) begin
|
||||
if (rate_counter == rate_period) begin
|
||||
exponential_counter <= exponential_counter + 1'b1;
|
||||
if (state == `ST_ATTACK || (exponential_counter + 1'b1) == exponential_counter_period) exponential_counter <= 8'h00;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Exponential Counter Period
|
||||
always @(posedge clock) begin
|
||||
if (reset) begin
|
||||
hold_zero <= 1'b1;
|
||||
exponential_counter_period <= 8'h00;
|
||||
end
|
||||
else if(ce_1m) begin
|
||||
if (gate_edge != gate) if (gate) hold_zero <= 1'b0;
|
||||
if ((envelope_pipeline) || ((rate_counter == rate_period) &&
|
||||
(state == `ST_ATTACK ||
|
||||
(exponential_counter + 1'b1) == exponential_counter_period) &&
|
||||
(!hold_zero)))
|
||||
begin
|
||||
case (state == `ST_ATTACK ? envelope + 1'b1 : envelope - 1'b1)
|
||||
8'hff: exponential_counter_period <= 8'd1;
|
||||
8'h5d: exponential_counter_period <= 8'd2;
|
||||
8'h36: exponential_counter_period <= 8'd4;
|
||||
8'h1a: exponential_counter_period <= 8'd8;
|
||||
8'h0e: exponential_counter_period <= 8'd16;
|
||||
8'h06: exponential_counter_period <= 8'd30;
|
||||
8'h00: begin
|
||||
exponential_counter_period <= 8'd1;
|
||||
hold_zero <= 1'b1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Rate Counter
|
||||
always @(posedge clock) begin
|
||||
if (reset) rate_counter <= 15'h7fff;
|
||||
else if(ce_1m) begin
|
||||
if (rate_counter == rate_period) rate_counter <= 15'h7fff;
|
||||
else rate_counter <= {rate_counter[1] ^ rate_counter[0], rate_counter[14:1]};
|
||||
end
|
||||
end
|
||||
|
||||
// Rate Period
|
||||
always @(posedge clock) begin
|
||||
if (reset)
|
||||
rate_period <= adsrtable[sus_rel[3:0]];
|
||||
else if(ce_1m) begin
|
||||
if (gate_edge != gate) begin
|
||||
if (gate) rate_period <= adsrtable[att_dec[7:4]];
|
||||
else rate_period <= adsrtable[sus_rel[3:0]];
|
||||
end
|
||||
case (state)
|
||||
`ST_ATTACK: rate_period <= adsrtable[att_dec[7:4]];
|
||||
`ST_DEC_SUS: rate_period <= adsrtable[att_dec[3:0]];
|
||||
default: rate_period <= adsrtable[sus_rel[3:0]];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
129
Commodore - 64_MiST/rtl/sid_filters.sv
Normal file
129
Commodore - 64_MiST/rtl/sid_filters.sv
Normal file
@@ -0,0 +1,129 @@
|
||||
|
||||
module sid_filters
|
||||
(
|
||||
input clk,
|
||||
input rst,
|
||||
input [ 7:0] Fc_lo,
|
||||
input [ 7:0] Fc_hi,
|
||||
input [ 7:0] Res_Filt,
|
||||
input [ 7:0] Mode_Vol,
|
||||
input [11:0] voice1,
|
||||
input [11:0] voice2,
|
||||
input [11:0] voice3,
|
||||
input input_valid,
|
||||
input [11:0] ext_in,
|
||||
input extfilter_en,
|
||||
|
||||
output reg [15:0] sound
|
||||
);
|
||||
|
||||
reg signed [17:0] Vhp;
|
||||
reg signed [17:0] Vbp;
|
||||
reg signed [17:0] w0;
|
||||
reg signed [17:0] q;
|
||||
|
||||
wire [10:0] divmul[16];
|
||||
assign divmul[0] = 1448;
|
||||
assign divmul[1] = 1328;
|
||||
assign divmul[2] = 1218;
|
||||
assign divmul[3] = 1117;
|
||||
assign divmul[4] = 1024;
|
||||
assign divmul[5] = 939;
|
||||
assign divmul[6] = 861;
|
||||
assign divmul[7] = 790;
|
||||
assign divmul[8] = 724;
|
||||
assign divmul[9] = 664;
|
||||
assign divmul[10] = 609;
|
||||
assign divmul[11] = 558;
|
||||
assign divmul[12] = 512;
|
||||
assign divmul[13] = 470;
|
||||
assign divmul[14] = 431;
|
||||
assign divmul[15] = 395;
|
||||
|
||||
wire [35:0] mul1 = w0 * Vhp;
|
||||
wire [35:0] mul2 = w0 * Vbp;
|
||||
wire [35:0] mul3 = q * Vbp;
|
||||
wire [35:0] mul4 = 18'd82355 * ({Fc_hi, Fc_lo[2:0]} + 1'b1);
|
||||
|
||||
// Filter
|
||||
always @(posedge clk) begin
|
||||
reg [17:0] dVbp;
|
||||
reg [17:0] Vlp;
|
||||
reg [17:0] dVlp;
|
||||
reg [17:0] Vi;
|
||||
reg [17:0] Vnf;
|
||||
reg [17:0] Vf;
|
||||
reg [21:0] mulr;
|
||||
reg [3:0] state;
|
||||
|
||||
if (rst) begin
|
||||
state <= 0;
|
||||
Vlp <= 0;
|
||||
Vbp <= 0;
|
||||
Vhp <= 0;
|
||||
end
|
||||
else begin
|
||||
case (state)
|
||||
0: if (input_valid) begin
|
||||
if(mulr[21] == mulr[20]) sound <= mulr[20:5];
|
||||
state <= state + 1'd1;
|
||||
Vi <= 0;
|
||||
Vnf <= 0;
|
||||
end
|
||||
1: state <= state + 1'd1;
|
||||
2: begin
|
||||
state <= state + 1'd1;
|
||||
w0 <= {mul4[35], mul4[28:12]};
|
||||
if (Res_Filt[0]) Vi <= Vi + (voice1 << 2);
|
||||
else Vnf <= Vnf + (voice1 << 2);
|
||||
end
|
||||
3: begin
|
||||
state <= state + 1'd1;
|
||||
if (Res_Filt[1]) Vi <= Vi + (voice2 << 2);
|
||||
else Vnf <= Vnf + (voice2 << 2);
|
||||
end
|
||||
4: begin
|
||||
state <= state + 1'd1;
|
||||
if (Res_Filt[2]) Vi <= Vi + (voice3 << 2);
|
||||
else if (!Mode_Vol[7]) Vnf <= Vnf + (voice3 << 2);
|
||||
dVbp <= {mul1[35], mul1[35:19]};
|
||||
end
|
||||
5: begin
|
||||
state <= state + 1'd1;
|
||||
if (Res_Filt[3]) Vi <= Vi + (ext_in << 2);
|
||||
else Vnf <= Vnf + (ext_in << 2);
|
||||
dVlp <= {mul2[35], mul2[35:19]};
|
||||
Vbp <= Vbp - dVbp;
|
||||
q <= divmul[Res_Filt[7:4]];
|
||||
end
|
||||
6: begin
|
||||
state <= state + 1'd1;
|
||||
Vlp <= Vlp - dVlp;
|
||||
Vf <= (Mode_Vol[5]) ? Vbp : 18'h00000;
|
||||
end
|
||||
7: begin
|
||||
state <= state + 1'd1;
|
||||
Vhp <= {mul3[35], mul3[26:10]} - Vlp;
|
||||
if(Mode_Vol[4]) Vf <= Vf + Vlp;
|
||||
end
|
||||
8: begin
|
||||
state <= state + 1'd1;
|
||||
Vhp <= Vhp - Vi;
|
||||
end
|
||||
9: begin
|
||||
state <= state + 1'd1;
|
||||
if(Mode_Vol[6]) Vf <= Vf + Vhp;
|
||||
end
|
||||
10: begin
|
||||
state <= state + 1'd1;
|
||||
Vf <= (extfilter_en) ? {~Vf + 1'b1} + Vnf : Vi + Vnf;
|
||||
end
|
||||
11: begin
|
||||
state <= 0;
|
||||
mulr <= Vf * Mode_Vol[3:0];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
353
Commodore - 64_MiST/rtl/sid_voice.sv
Normal file
353
Commodore - 64_MiST/rtl/sid_voice.sv
Normal file
@@ -0,0 +1,353 @@
|
||||
|
||||
// altera message_off 10030
|
||||
module sid_voice
|
||||
(
|
||||
input clock,
|
||||
input ce_1m,
|
||||
input reset,
|
||||
input [7:0] freq_lo,
|
||||
input [7:0] freq_hi,
|
||||
input [7:0] pw_lo,
|
||||
input [3:0] pw_hi,
|
||||
input [7:0] control,
|
||||
input [7:0] att_dec,
|
||||
input [7:0] sus_rel,
|
||||
input osc_msb_in,
|
||||
|
||||
output osc_msb_out,
|
||||
output [11:0] signal_out,
|
||||
output [ 7:0] osc_out,
|
||||
output [ 7:0] env_out
|
||||
);
|
||||
|
||||
// Internal Signals
|
||||
reg [23:0] oscillator;
|
||||
reg osc_edge;
|
||||
reg osc_msb_in_prv;
|
||||
reg [11:0] triangle;
|
||||
reg [11:0] sawtooth;
|
||||
reg [11:0] pulse;
|
||||
reg [11:0] noise;
|
||||
reg [22:0] lfsr_noise;
|
||||
wire [ 7:0] envelope;
|
||||
reg [11:0] wave_out;
|
||||
reg [19:0] dca_out;
|
||||
|
||||
`define noise_ctrl control[7]
|
||||
`define pulse_ctrl control[6]
|
||||
`define saw_ctrl control[5]
|
||||
`define tri_ctrl control[4]
|
||||
`define test_ctrl control[3]
|
||||
`define ringmod_ctrl control[2]
|
||||
`define sync_ctrl control[1]
|
||||
|
||||
// Signal Assignments
|
||||
assign osc_msb_out = oscillator[23];
|
||||
assign signal_out = dca_out[19:8];
|
||||
assign osc_out = wave_out[11:4];
|
||||
assign env_out = envelope;
|
||||
|
||||
// Digital Controlled Amplifier
|
||||
always @(posedge clock) if(ce_1m) dca_out <= wave_out * envelope;
|
||||
|
||||
// Envelope Instantiation
|
||||
sid_envelope adsr
|
||||
(
|
||||
.clock(clock),
|
||||
.ce_1m(ce_1m),
|
||||
.reset(reset),
|
||||
.gate(control[0]),
|
||||
.att_dec(att_dec),
|
||||
.sus_rel(sus_rel),
|
||||
.envelope(envelope)
|
||||
);
|
||||
|
||||
// Phase Accumulating Oscillator
|
||||
always @(posedge clock) begin
|
||||
if(ce_1m) begin
|
||||
osc_msb_in_prv <= osc_msb_in;
|
||||
if (reset || `test_ctrl || ((`sync_ctrl) && (!osc_msb_in) && (osc_msb_in != osc_msb_in_prv)))
|
||||
oscillator <= 0;
|
||||
else
|
||||
oscillator <= oscillator + {freq_hi, freq_lo};
|
||||
end
|
||||
end
|
||||
|
||||
// Waveform Generator
|
||||
always @(posedge clock) begin
|
||||
if (reset) begin
|
||||
triangle <= 0;
|
||||
sawtooth <= 0;
|
||||
pulse <= 0;
|
||||
noise <= 0;
|
||||
osc_edge <= 0;
|
||||
lfsr_noise <= 23'h7fffff;
|
||||
end
|
||||
else if(ce_1m) begin
|
||||
triangle <= (`ringmod_ctrl) ?
|
||||
{({11{osc_msb_in}} ^ {{11{oscillator[23]}}}) ^ oscillator[22:12], 1'b0} :
|
||||
{{11{oscillator[23]}} ^ oscillator[22:12], 1'b0};
|
||||
|
||||
sawtooth <= oscillator[23:12];
|
||||
|
||||
pulse <= (`test_ctrl) ? 12'hfff :
|
||||
(oscillator[23:12] >= {pw_hi, pw_lo}) ? {12{1'b1}} :
|
||||
{12{1'b0}};
|
||||
|
||||
noise <= {lfsr_noise[21], lfsr_noise[19], lfsr_noise[15],
|
||||
lfsr_noise[12], lfsr_noise[10], lfsr_noise[6],
|
||||
lfsr_noise[3], lfsr_noise[1], 4'b0000};
|
||||
|
||||
osc_edge <= (oscillator[19] && !osc_edge) ? 1'b1 :
|
||||
(!oscillator[19] && osc_edge) ? 1'b0 :
|
||||
osc_edge;
|
||||
|
||||
lfsr_noise <= (oscillator[19] && !osc_edge) ?
|
||||
{lfsr_noise[21:0], (lfsr_noise[22] | `test_ctrl) ^ lfsr_noise[17]} :
|
||||
lfsr_noise;
|
||||
end
|
||||
end
|
||||
|
||||
// Waveform Output Selector
|
||||
always @(*) begin
|
||||
case (control[7:4])
|
||||
4'b0001: wave_out = triangle;
|
||||
4'b0010: wave_out = sawtooth;
|
||||
4'b0011: wave_out = {wave__st[sawtooth], 4'b0000};
|
||||
4'b0100: wave_out = pulse;
|
||||
4'b0101: wave_out = {wave_p_t[triangle[11:1]], 4'b0000} & pulse;
|
||||
4'b0110: wave_out = {wave_ps_[sawtooth], 4'b0000} & pulse;
|
||||
4'b0111: wave_out = {wave_pst[sawtooth], 4'b0000} & pulse;
|
||||
4'b1000: wave_out = noise;
|
||||
default: wave_out = 0;
|
||||
endcase
|
||||
end
|
||||
|
||||
//
|
||||
// convert combinatorial logic to ROM (Sorgelig)
|
||||
//
|
||||
|
||||
reg [7:0] wave__st[4096];
|
||||
reg [7:0] wave_p_t[2048];
|
||||
reg [7:0] wave_ps_[4096];
|
||||
reg [7:0] wave_pst[4096];
|
||||
|
||||
initial begin
|
||||
integer i;
|
||||
for(i = 0; i<4096; i=i+1) wave__st[i] =
|
||||
(i < 'h07e) ? 8'h00 : (i < 'h080) ? 8'h03 : (i < 'h0fc) ? 8'h00 : (i < 'h100) ? 8'h07 :
|
||||
(i < 'h17e) ? 8'h00 : (i < 'h180) ? 8'h03 : (i < 'h1f8) ? 8'h00 : (i < 'h1fc) ? 8'h0e :
|
||||
(i < 'h200) ? 8'h0f : (i < 'h27e) ? 8'h00 : (i < 'h280) ? 8'h03 : (i < 'h2fc) ? 8'h00 :
|
||||
(i < 'h300) ? 8'h07 : (i < 'h37e) ? 8'h00 : (i < 'h380) ? 8'h03 : (i < 'h3bf) ? 8'h00 :
|
||||
(i < 'h3c0) ? 8'h01 : (i < 'h3f0) ? 8'h00 : (i < 'h3f8) ? 8'h1c : (i < 'h3fa) ? 8'h1e :
|
||||
(i < 'h400) ? 8'h1f : (i < 'h47e) ? 8'h00 : (i < 'h480) ? 8'h03 : (i < 'h4fc) ? 8'h00 :
|
||||
(i < 'h500) ? 8'h07 : (i < 'h57e) ? 8'h00 : (i < 'h580) ? 8'h03 : (i < 'h5f8) ? 8'h00 :
|
||||
(i < 'h5fc) ? 8'h0e : (i < 'h5ff) ? 8'h0f : (i < 'h600) ? 8'h1f : (i < 'h67e) ? 8'h00 :
|
||||
(i < 'h680) ? 8'h03 : (i < 'h6fc) ? 8'h00 : (i < 'h700) ? 8'h07 : (i < 'h77e) ? 8'h00 :
|
||||
(i < 'h780) ? 8'h03 : (i < 'h7bf) ? 8'h00 : (i < 'h7c0) ? 8'h01 : (i < 'h7e0) ? 8'h00 :
|
||||
(i < 'h7f0) ? 8'h38 : (i < 'h7f7) ? 8'h3c : (i < 'h7f8) ? 8'h3e : (i < 'h800) ? 8'h7f :
|
||||
(i < 'h87e) ? 8'h00 : (i < 'h880) ? 8'h03 : (i < 'h8fc) ? 8'h00 : (i < 'h900) ? 8'h07 :
|
||||
(i < 'h97e) ? 8'h00 : (i < 'h980) ? 8'h03 : (i < 'h9f8) ? 8'h00 : (i < 'h9fc) ? 8'h0e :
|
||||
(i < 'ha00) ? 8'h0f : (i < 'ha7e) ? 8'h00 : (i < 'ha80) ? 8'h03 : (i < 'hafc) ? 8'h00 :
|
||||
(i < 'hb00) ? 8'h07 : (i < 'hb7e) ? 8'h00 : (i < 'hb80) ? 8'h03 : (i < 'hbbf) ? 8'h00 :
|
||||
(i < 'hbc0) ? 8'h01 : (i < 'hbf0) ? 8'h00 : (i < 'hbf8) ? 8'h1c : (i < 'hbfa) ? 8'h1e :
|
||||
(i < 'hbfe) ? 8'h1f : (i < 'hc00) ? 8'h3f : (i < 'hc7e) ? 8'h00 : (i < 'hc80) ? 8'h03 :
|
||||
(i < 'hcfc) ? 8'h00 : (i < 'hd00) ? 8'h07 : (i < 'hd7e) ? 8'h00 : (i < 'hd80) ? 8'h03 :
|
||||
(i < 'hdbf) ? 8'h00 : (i < 'hdc0) ? 8'h01 : (i < 'hdf8) ? 8'h00 : (i < 'hdfc) ? 8'h0e :
|
||||
(i < 'hdfe) ? 8'h0f : (i < 'he00) ? 8'h1f : (i < 'he7c) ? 8'h00 : (i < 'he7d) ? 8'h80 :
|
||||
(i < 'he7e) ? 8'h00 : (i < 'he80) ? 8'h83 : (i < 'hefc) ? 8'h80 : (i < 'heff) ? 8'h87 :
|
||||
(i < 'hf00) ? 8'h8f : (i < 'hf01) ? 8'hc0 : (i < 'hf03) ? 8'he0 : (i < 'hf05) ? 8'hc0 :
|
||||
(i < 'hf09) ? 8'he0 : (i < 'hf11) ? 8'hc0 : (i < 'hf13) ? 8'he0 : (i < 'hf18) ? 8'hc0 :
|
||||
(i < 'hf19) ? 8'he0 : (i < 'hf21) ? 8'hc0 : (i < 'hf23) ? 8'he0 : (i < 'hf25) ? 8'hc0 :
|
||||
(i < 'hf2b) ? 8'he0 : (i < 'hf2c) ? 8'hc0 : (i < 'hf2d) ? 8'he0 : (i < 'hf2e) ? 8'hc0 :
|
||||
(i < 'hf7e) ? 8'he0 : (i < 'hf80) ? 8'he3 : (i < 'hfbf) ? 8'hf0 : (i < 'hfc0) ? 8'hf1 :
|
||||
(i < 'hfe0) ? 8'hf8 : (i < 'hff0) ? 8'hfc : (i < 'hff8) ? 8'hfe : 8'hff;
|
||||
|
||||
for(i = 0; i<2048; i=i+1) wave_p_t[i] =
|
||||
(i < 'h0ff) ? 8'h00 : (i < 'h100) ? 8'h07 : (i < 'h1fb) ? 8'h00 : (i < 'h1fc) ? 8'h1c :
|
||||
(i < 'h1fd) ? 8'h00 : (i < 'h1fe) ? 8'h3c : (i < 'h200) ? 8'h3f : (i < 'h2fd) ? 8'h00 :
|
||||
(i < 'h2fe) ? 8'h0c : (i < 'h2ff) ? 8'h5e : (i < 'h300) ? 8'h5f : (i < 'h377) ? 8'h00 :
|
||||
(i < 'h378) ? 8'h40 : (i < 'h37b) ? 8'h00 : (i < 'h37d) ? 8'h40 : (i < 'h37f) ? 8'h60 :
|
||||
(i < 'h380) ? 8'h6f : (i < 'h39f) ? 8'h00 : (i < 'h3a0) ? 8'h40 : (i < 'h3ae) ? 8'h00 :
|
||||
(i < 'h3b0) ? 8'h40 : (i < 'h3b3) ? 8'h00 : (i < 'h3b7) ? 8'h40 : (i < 'h3b8) ? 8'h60 :
|
||||
(i < 'h3ba) ? 8'h40 : (i < 'h3be) ? 8'h60 : (i < 'h3bf) ? 8'h70 : (i < 'h3c0) ? 8'h77 :
|
||||
(i < 'h3c5) ? 8'h00 : (i < 'h3cd) ? 8'h40 : (i < 'h3d0) ? 8'h60 : (i < 'h3d3) ? 8'h40 :
|
||||
(i < 'h3d7) ? 8'h60 : (i < 'h3d8) ? 8'h70 : (i < 'h3db) ? 8'h60 : (i < 'h3de) ? 8'h70 :
|
||||
(i < 'h3df) ? 8'h78 : (i < 'h3e0) ? 8'h7b : (i < 'h3e3) ? 8'h60 : (i < 'h3e4) ? 8'h70 :
|
||||
(i < 'h3e5) ? 8'h60 : (i < 'h3eb) ? 8'h70 : (i < 'h3ef) ? 8'h78 : (i < 'h3f0) ? 8'h7c :
|
||||
(i < 'h3f3) ? 8'h78 : (i < 'h3f4) ? 8'h7c : (i < 'h3f5) ? 8'h78 : (i < 'h3f7) ? 8'h7c :
|
||||
(i < 'h3f8) ? 8'h7e : (i < 'h3f9) ? 8'h7c : (i < 'h3fb) ? 8'h7e : (i < 'h400) ? 8'h7f :
|
||||
(i < 'h47f) ? 8'h00 : (i < 'h480) ? 8'h80 : (i < 'h4bd) ? 8'h00 : (i < 'h4c0) ? 8'h80 :
|
||||
(i < 'h4cf) ? 8'h00 : (i < 'h4d0) ? 8'h80 : (i < 'h4d7) ? 8'h00 : (i < 'h4d8) ? 8'h80 :
|
||||
(i < 'h4da) ? 8'h00 : (i < 'h4e0) ? 8'h80 : (i < 'h4e3) ? 8'h00 : (i < 'h4fe) ? 8'h80 :
|
||||
(i < 'h4ff) ? 8'h8e : (i < 'h500) ? 8'h9f : (i < 'h51f) ? 8'h00 : (i < 'h520) ? 8'h80 :
|
||||
(i < 'h52b) ? 8'h00 : (i < 'h52c) ? 8'h80 : (i < 'h52d) ? 8'h00 : (i < 'h530) ? 8'h80 :
|
||||
(i < 'h532) ? 8'h00 : (i < 'h540) ? 8'h80 : (i < 'h543) ? 8'h00 : (i < 'h544) ? 8'h80 :
|
||||
(i < 'h545) ? 8'h00 : (i < 'h57f) ? 8'h80 : (i < 'h580) ? 8'haf : (i < 'h5bb) ? 8'h80 :
|
||||
(i < 'h5bf) ? 8'ha0 : (i < 'h5c0) ? 8'hb7 : (i < 'h5cf) ? 8'h80 : (i < 'h5d0) ? 8'ha0 :
|
||||
(i < 'h5d6) ? 8'h80 : (i < 'h5db) ? 8'ha0 : (i < 'h5dc) ? 8'hb0 : (i < 'h5dd) ? 8'ha0 :
|
||||
(i < 'h5df) ? 8'hb0 : (i < 'h5e0) ? 8'hbb : (i < 'h5e6) ? 8'ha0 : (i < 'h5e8) ? 8'hb0 :
|
||||
(i < 'h5e9) ? 8'ha0 : (i < 'h5eb) ? 8'hb0 : (i < 'h5ec) ? 8'hb8 : (i < 'h5ed) ? 8'hb0 :
|
||||
(i < 'h5ef) ? 8'hb8 : (i < 'h5f0) ? 8'hbc : (i < 'h5f1) ? 8'hb0 : (i < 'h5f5) ? 8'hb8 :
|
||||
(i < 'h5f7) ? 8'hbc : (i < 'h5f8) ? 8'hbe : (i < 'h5fa) ? 8'hbc : (i < 'h5fb) ? 8'hbe :
|
||||
(i < 'h5fc) ? 8'hbf : (i < 'h5fd) ? 8'hbe : (i < 'h600) ? 8'hbf : (i < 'h63e) ? 8'h80 :
|
||||
(i < 'h640) ? 8'hc0 : (i < 'h657) ? 8'h80 : (i < 'h658) ? 8'hc0 : (i < 'h65a) ? 8'h80 :
|
||||
(i < 'h660) ? 8'hc0 : (i < 'h663) ? 8'h80 : (i < 'h664) ? 8'hc0 : (i < 'h665) ? 8'h80 :
|
||||
(i < 'h67f) ? 8'hc0 : (i < 'h680) ? 8'hcf : (i < 'h686) ? 8'h80 : (i < 'h689) ? 8'hc0 :
|
||||
(i < 'h68a) ? 8'h80 : (i < 'h6bf) ? 8'hc0 : (i < 'h6c0) ? 8'hd7 : (i < 'h6dd) ? 8'hc0 :
|
||||
(i < 'h6df) ? 8'hd0 : (i < 'h6e0) ? 8'hd9 : (i < 'h6e7) ? 8'hc0 : (i < 'h6e8) ? 8'hd0 :
|
||||
(i < 'h6e9) ? 8'hc0 : (i < 'h6ed) ? 8'hd0 : (i < 'h6ef) ? 8'hd8 : (i < 'h6f0) ? 8'hdc :
|
||||
(i < 'h6f2) ? 8'hd0 : (i < 'h6f5) ? 8'hd8 : (i < 'h6f7) ? 8'hdc : (i < 'h6f8) ? 8'hde :
|
||||
(i < 'h6fa) ? 8'hdc : (i < 'h6fb) ? 8'hde : (i < 'h6fc) ? 8'hdf : (i < 'h6fd) ? 8'hde :
|
||||
(i < 'h700) ? 8'hdf : (i < 'h71b) ? 8'hc0 : (i < 'h71c) ? 8'he0 : (i < 'h71d) ? 8'hc0 :
|
||||
(i < 'h720) ? 8'he0 : (i < 'h727) ? 8'hc0 : (i < 'h728) ? 8'he0 : (i < 'h72a) ? 8'hc0 :
|
||||
(i < 'h73f) ? 8'he0 : (i < 'h740) ? 8'he7 : (i < 'h75f) ? 8'he0 : (i < 'h760) ? 8'he8 :
|
||||
(i < 'h76e) ? 8'he0 : (i < 'h76f) ? 8'he8 : (i < 'h770) ? 8'hec : (i < 'h773) ? 8'he0 :
|
||||
(i < 'h776) ? 8'he8 : (i < 'h777) ? 8'hec : (i < 'h778) ? 8'hee : (i < 'h77b) ? 8'hec :
|
||||
(i < 'h77d) ? 8'hee : (i < 'h780) ? 8'hef : (i < 'h78d) ? 8'he0 : (i < 'h790) ? 8'hf0 :
|
||||
(i < 'h792) ? 8'he0 : (i < 'h7af) ? 8'hf0 : (i < 'h7b0) ? 8'hf4 : (i < 'h7b7) ? 8'hf0 :
|
||||
(i < 'h7b8) ? 8'hf4 : (i < 'h7b9) ? 8'hf0 : (i < 'h7bb) ? 8'hf4 : (i < 'h7bd) ? 8'hf6 :
|
||||
(i < 'h7c0) ? 8'hf7 : (i < 'h7c3) ? 8'hf0 : (i < 'h7c4) ? 8'hf8 : (i < 'h7c5) ? 8'hf0 :
|
||||
(i < 'h7db) ? 8'hf8 : (i < 'h7dd) ? 8'hfa : (i < 'h7e0) ? 8'hfb : (i < 'h7e1) ? 8'hf8 :
|
||||
(i < 'h7ed) ? 8'hfc : (i < 'h7f0) ? 8'hfd : (i < 'h7f8) ? 8'hfe : 8'hff;
|
||||
|
||||
for(i = 0; i<4096; i=i+1) wave_ps_[i] =
|
||||
(i < 'h07f) ? 8'h00 : (i < 'h080) ? 8'h03 : (i < 'h0bf) ? 8'h00 : (i < 'h0c0) ? 8'h01 :
|
||||
(i < 'h0ff) ? 8'h00 : (i < 'h100) ? 8'h0f : (i < 'h17f) ? 8'h00 : (i < 'h180) ? 8'h07 :
|
||||
(i < 'h1bf) ? 8'h00 : (i < 'h1c0) ? 8'h03 : (i < 'h1df) ? 8'h00 : (i < 'h1e0) ? 8'h01 :
|
||||
(i < 'h1fd) ? 8'h00 : (i < 'h1ff) ? 8'h07 : (i < 'h200) ? 8'h1f : (i < 'h27f) ? 8'h00 :
|
||||
(i < 'h280) ? 8'h03 : (i < 'h2bf) ? 8'h00 : (i < 'h2c0) ? 8'h03 : (i < 'h2df) ? 8'h00 :
|
||||
(i < 'h2e0) ? 8'h01 : (i < 'h2fe) ? 8'h00 : (i < 'h2ff) ? 8'h01 : (i < 'h300) ? 8'h0f :
|
||||
(i < 'h33f) ? 8'h00 : (i < 'h340) ? 8'h01 : (i < 'h37f) ? 8'h00 : (i < 'h380) ? 8'h17 :
|
||||
(i < 'h3bf) ? 8'h00 : (i < 'h3c0) ? 8'h3b : (i < 'h3df) ? 8'h00 : (i < 'h3e0) ? 8'h3d :
|
||||
(i < 'h3ef) ? 8'h00 : (i < 'h3f0) ? 8'h3e : (i < 'h3f7) ? 8'h00 : (i < 'h3f8) ? 8'h3f :
|
||||
(i < 'h3f9) ? 8'h00 : (i < 'h3fa) ? 8'h0c : (i < 'h3fb) ? 8'h1c : (i < 'h3fc) ? 8'h3f :
|
||||
(i < 'h3fd) ? 8'h1e : (i < 'h400) ? 8'h3f : (i < 'h47f) ? 8'h00 : (i < 'h480) ? 8'h03 :
|
||||
(i < 'h4bf) ? 8'h00 : (i < 'h4c0) ? 8'h01 : (i < 'h4ff) ? 8'h00 : (i < 'h500) ? 8'h0f :
|
||||
(i < 'h53f) ? 8'h00 : (i < 'h540) ? 8'h01 : (i < 'h57f) ? 8'h00 : (i < 'h580) ? 8'h07 :
|
||||
(i < 'h5bf) ? 8'h00 : (i < 'h5c0) ? 8'h0b : (i < 'h5df) ? 8'h00 : (i < 'h5e0) ? 8'h0a :
|
||||
(i < 'h5ef) ? 8'h00 : (i < 'h5f0) ? 8'h5e : (i < 'h5f7) ? 8'h00 : (i < 'h5f8) ? 8'h5f :
|
||||
(i < 'h5fb) ? 8'h00 : (i < 'h5fc) ? 8'h5f : (i < 'h5fd) ? 8'h0c : (i < 'h600) ? 8'h5f :
|
||||
(i < 'h63f) ? 8'h00 : (i < 'h640) ? 8'h01 : (i < 'h67f) ? 8'h00 : (i < 'h680) ? 8'h47 :
|
||||
(i < 'h6bf) ? 8'h00 : (i < 'h6c0) ? 8'h43 : (i < 'h6df) ? 8'h00 : (i < 'h6e0) ? 8'h65 :
|
||||
(i < 'h6ef) ? 8'h00 : (i < 'h6f0) ? 8'h6e : (i < 'h6f7) ? 8'h00 : (i < 'h6f8) ? 8'h6f :
|
||||
(i < 'h6f9) ? 8'h00 : (i < 'h6fb) ? 8'h40 : (i < 'h6fc) ? 8'h6f : (i < 'h6fd) ? 8'h40 :
|
||||
(i < 'h700) ? 8'h6f : (i < 'h73f) ? 8'h00 : (i < 'h740) ? 8'h63 : (i < 'h75e) ? 8'h00 :
|
||||
(i < 'h75f) ? 8'h40 : (i < 'h760) ? 8'h61 : (i < 'h767) ? 8'h00 : (i < 'h768) ? 8'h40 :
|
||||
(i < 'h76b) ? 8'h00 : (i < 'h76c) ? 8'h40 : (i < 'h76d) ? 8'h00 : (i < 'h76f) ? 8'h40 :
|
||||
(i < 'h770) ? 8'h70 : (i < 'h772) ? 8'h00 : (i < 'h777) ? 8'h40 : (i < 'h778) ? 8'h70 :
|
||||
(i < 'h779) ? 8'h40 : (i < 'h77b) ? 8'h60 : (i < 'h77c) ? 8'h77 : (i < 'h77d) ? 8'h60 :
|
||||
(i < 'h780) ? 8'h77 : (i < 'h78f) ? 8'h00 : (i < 'h790) ? 8'h40 : (i < 'h796) ? 8'h00 :
|
||||
(i < 'h797) ? 8'h40 : (i < 'h798) ? 8'h60 : (i < 'h799) ? 8'h00 : (i < 'h79b) ? 8'h40 :
|
||||
(i < 'h79c) ? 8'h60 : (i < 'h79d) ? 8'h40 : (i < 'h79f) ? 8'h60 : (i < 'h7a0) ? 8'h79 :
|
||||
(i < 'h7a1) ? 8'h00 : (i < 'h7a7) ? 8'h40 : (i < 'h7a8) ? 8'h60 : (i < 'h7ab) ? 8'h40 :
|
||||
(i < 'h7af) ? 8'h60 : (i < 'h7b0) ? 8'h78 : (i < 'h7b1) ? 8'h40 : (i < 'h7b7) ? 8'h60 :
|
||||
(i < 'h7b8) ? 8'h78 : (i < 'h7b9) ? 8'h60 : (i < 'h7bb) ? 8'h70 : (i < 'h7bc) ? 8'h78 :
|
||||
(i < 'h7bd) ? 8'h70 : (i < 'h7be) ? 8'h79 : (i < 'h7c0) ? 8'h7b : (i < 'h7c7) ? 8'h60 :
|
||||
(i < 'h7c8) ? 8'h70 : (i < 'h7cb) ? 8'h60 : (i < 'h7cc) ? 8'h70 : (i < 'h7cd) ? 8'h60 :
|
||||
(i < 'h7cf) ? 8'h70 : (i < 'h7d0) ? 8'h7c : (i < 'h7d1) ? 8'h60 : (i < 'h7d7) ? 8'h70 :
|
||||
(i < 'h7d8) ? 8'h7c : (i < 'h7d9) ? 8'h70 : (i < 'h7db) ? 8'h78 : (i < 'h7dc) ? 8'h7c :
|
||||
(i < 'h7dd) ? 8'h78 : (i < 'h7df) ? 8'h7c : (i < 'h7e0) ? 8'h7d : (i < 'h7e1) ? 8'h70 :
|
||||
(i < 'h7e7) ? 8'h78 : (i < 'h7e8) ? 8'h7c : (i < 'h7e9) ? 8'h78 : (i < 'h7eb) ? 8'h7c :
|
||||
(i < 'h7ec) ? 8'h7e : (i < 'h7ed) ? 8'h7c : (i < 'h7f0) ? 8'h7e : (i < 'h7f3) ? 8'h7c :
|
||||
(i < 'h7f5) ? 8'h7e : (i < 'h7f8) ? 8'h7f : (i < 'h7f9) ? 8'h7e : (i < 'h7ff) ? 8'h7f :
|
||||
(i < 'h800) ? 8'hff : (i < 'h87f) ? 8'h00 : (i < 'h880) ? 8'h03 : (i < 'h8bf) ? 8'h00 :
|
||||
(i < 'h8c0) ? 8'h01 : (i < 'h8ff) ? 8'h00 : (i < 'h900) ? 8'h8f : (i < 'h93f) ? 8'h00 :
|
||||
(i < 'h940) ? 8'h01 : (i < 'h97f) ? 8'h00 : (i < 'h980) ? 8'h87 : (i < 'h9bf) ? 8'h00 :
|
||||
(i < 'h9c0) ? 8'h83 : (i < 'h9de) ? 8'h00 : (i < 'h9df) ? 8'h80 : (i < 'h9e0) ? 8'h8d :
|
||||
(i < 'h9e7) ? 8'h00 : (i < 'h9e8) ? 8'h80 : (i < 'h9eb) ? 8'h00 : (i < 'h9ec) ? 8'h80 :
|
||||
(i < 'h9ed) ? 8'h00 : (i < 'h9ef) ? 8'h80 : (i < 'h9f0) ? 8'h8e : (i < 'h9f3) ? 8'h00 :
|
||||
(i < 'h9f7) ? 8'h80 : (i < 'h9f8) ? 8'h8f : (i < 'h9fb) ? 8'h80 : (i < 'h9fc) ? 8'h9f :
|
||||
(i < 'h9fd) ? 8'h80 : (i < 'ha00) ? 8'h9f : (i < 'ha3f) ? 8'h00 : (i < 'ha40) ? 8'h01 :
|
||||
(i < 'ha6f) ? 8'h00 : (i < 'ha70) ? 8'h80 : (i < 'ha77) ? 8'h00 : (i < 'ha78) ? 8'h80 :
|
||||
(i < 'ha7b) ? 8'h00 : (i < 'ha7c) ? 8'h80 : (i < 'ha7d) ? 8'h00 : (i < 'ha7f) ? 8'h80 :
|
||||
(i < 'ha80) ? 8'h87 : (i < 'ha9f) ? 8'h00 : (i < 'haa0) ? 8'h80 : (i < 'haaf) ? 8'h00 :
|
||||
(i < 'hab0) ? 8'h80 : (i < 'hab7) ? 8'h00 : (i < 'hab8) ? 8'h80 : (i < 'habb) ? 8'h00 :
|
||||
(i < 'habf) ? 8'h80 : (i < 'hac0) ? 8'h83 : (i < 'hacf) ? 8'h00 : (i < 'had0) ? 8'h80 :
|
||||
(i < 'had5) ? 8'h00 : (i < 'had8) ? 8'h80 : (i < 'had9) ? 8'h00 : (i < 'hadf) ? 8'h80 :
|
||||
(i < 'hae0) ? 8'h81 : (i < 'haef) ? 8'h80 : (i < 'haf0) ? 8'h84 : (i < 'haf7) ? 8'h80 :
|
||||
(i < 'haf8) ? 8'h87 : (i < 'hafb) ? 8'h80 : (i < 'hafc) ? 8'h87 : (i < 'hafd) ? 8'h80 :
|
||||
(i < 'hafe) ? 8'h8f : (i < 'hb00) ? 8'haf : (i < 'hb0f) ? 8'h00 : (i < 'hb10) ? 8'h80 :
|
||||
(i < 'hb17) ? 8'h00 : (i < 'hb18) ? 8'h80 : (i < 'hb1b) ? 8'h00 : (i < 'hb20) ? 8'h80 :
|
||||
(i < 'hb23) ? 8'h00 : (i < 'hb24) ? 8'h80 : (i < 'hb26) ? 8'h00 : (i < 'hb28) ? 8'h80 :
|
||||
(i < 'hb29) ? 8'h00 : (i < 'hb3f) ? 8'h80 : (i < 'hb40) ? 8'h83 : (i < 'hb5f) ? 8'h80 :
|
||||
(i < 'hb60) ? 8'h81 : (i < 'hb6f) ? 8'h80 : (i < 'hb70) ? 8'ha0 : (i < 'hb77) ? 8'h80 :
|
||||
(i < 'hb78) ? 8'ha0 : (i < 'hb7b) ? 8'h80 : (i < 'hb7c) ? 8'ha0 : (i < 'hb7d) ? 8'h80 :
|
||||
(i < 'hb7e) ? 8'ha3 : (i < 'hb80) ? 8'hb7 : (i < 'hb9f) ? 8'h80 : (i < 'hba0) ? 8'hb1 :
|
||||
(i < 'hbaf) ? 8'h80 : (i < 'hbb0) ? 8'hb0 : (i < 'hbb7) ? 8'h80 : (i < 'hbb8) ? 8'hb0 :
|
||||
(i < 'hbb9) ? 8'h80 : (i < 'hbbb) ? 8'ha0 : (i < 'hbbc) ? 8'hb0 : (i < 'hbbd) ? 8'ha0 :
|
||||
(i < 'hbbe) ? 8'hb8 : (i < 'hbbf) ? 8'hb9 : (i < 'hbc0) ? 8'hbb : (i < 'hbc7) ? 8'h80 :
|
||||
(i < 'hbc8) ? 8'ha0 : (i < 'hbcb) ? 8'h80 : (i < 'hbcc) ? 8'ha0 : (i < 'hbcd) ? 8'h80 :
|
||||
(i < 'hbcf) ? 8'ha0 : (i < 'hbd0) ? 8'hb8 : (i < 'hbd1) ? 8'h80 : (i < 'hbd7) ? 8'ha0 :
|
||||
(i < 'hbd8) ? 8'hb8 : (i < 'hbd9) ? 8'ha0 : (i < 'hbdb) ? 8'hb0 : (i < 'hbdc) ? 8'hb8 :
|
||||
(i < 'hbdd) ? 8'hb0 : (i < 'hbdf) ? 8'hbc : (i < 'hbe0) ? 8'hbd : (i < 'hbe1) ? 8'ha0 :
|
||||
(i < 'hbe5) ? 8'hb0 : (i < 'hbe7) ? 8'hb8 : (i < 'hbe8) ? 8'hbc : (i < 'hbe9) ? 8'hb0 :
|
||||
(i < 'hbeb) ? 8'hb8 : (i < 'hbec) ? 8'hbc : (i < 'hbed) ? 8'hb8 : (i < 'hbee) ? 8'hbc :
|
||||
(i < 'hbf0) ? 8'hbe : (i < 'hbf1) ? 8'hb8 : (i < 'hbf3) ? 8'hbc : (i < 'hbf4) ? 8'hbe :
|
||||
(i < 'hbf5) ? 8'hbc : (i < 'hbf7) ? 8'hbe : (i < 'hbf8) ? 8'hbf : (i < 'hbf9) ? 8'hbe :
|
||||
(i < 'hc00) ? 8'hbf : (i < 'hc03) ? 8'h00 : (i < 'hc04) ? 8'h80 : (i < 'hc07) ? 8'h00 :
|
||||
(i < 'hc08) ? 8'h80 : (i < 'hc0b) ? 8'h00 : (i < 'hc0c) ? 8'h80 : (i < 'hc0f) ? 8'h00 :
|
||||
(i < 'hc10) ? 8'h80 : (i < 'hc11) ? 8'h00 : (i < 'hc18) ? 8'h80 : (i < 'hc19) ? 8'h00 :
|
||||
(i < 'hc3f) ? 8'h80 : (i < 'hc40) ? 8'h81 : (i < 'hc7f) ? 8'h80 : (i < 'hc80) ? 8'hc7 :
|
||||
(i < 'hcbe) ? 8'h80 : (i < 'hcbf) ? 8'hc0 : (i < 'hcc0) ? 8'hc3 : (i < 'hccf) ? 8'h80 :
|
||||
(i < 'hcd0) ? 8'hc0 : (i < 'hcd7) ? 8'h80 : (i < 'hcd8) ? 8'hc0 : (i < 'hcdb) ? 8'h80 :
|
||||
(i < 'hcdc) ? 8'hc0 : (i < 'hcdd) ? 8'h80 : (i < 'hcdf) ? 8'hc0 : (i < 'hce0) ? 8'hc1 :
|
||||
(i < 'hce7) ? 8'h80 : (i < 'hce8) ? 8'hc0 : (i < 'hceb) ? 8'h80 : (i < 'hcf7) ? 8'hc0 :
|
||||
(i < 'hcf8) ? 8'hc7 : (i < 'hcfb) ? 8'hc0 : (i < 'hcfc) ? 8'hc7 : (i < 'hcfd) ? 8'hc0 :
|
||||
(i < 'hd00) ? 8'hcf : (i < 'hd1f) ? 8'h80 : (i < 'hd20) ? 8'hc0 : (i < 'hd2f) ? 8'h80 :
|
||||
(i < 'hd30) ? 8'hc0 : (i < 'hd36) ? 8'h80 : (i < 'hd38) ? 8'hc0 : (i < 'hd39) ? 8'h80 :
|
||||
(i < 'hd3f) ? 8'hc0 : (i < 'hd40) ? 8'hc3 : (i < 'hd47) ? 8'h80 : (i < 'hd48) ? 8'hc0 :
|
||||
(i < 'hd4b) ? 8'h80 : (i < 'hd4c) ? 8'hc0 : (i < 'hd4d) ? 8'h80 : (i < 'hd50) ? 8'hc0 :
|
||||
(i < 'hd51) ? 8'h80 : (i < 'hd5f) ? 8'hc0 : (i < 'hd60) ? 8'hc1 : (i < 'hd7d) ? 8'hc0 :
|
||||
(i < 'hd7e) ? 8'hc1 : (i < 'hd7f) ? 8'hc7 : (i < 'hd80) ? 8'hd7 : (i < 'hdaf) ? 8'hc0 :
|
||||
(i < 'hdb0) ? 8'hd0 : (i < 'hdb7) ? 8'hc0 : (i < 'hdb8) ? 8'hd0 : (i < 'hdbb) ? 8'hc0 :
|
||||
(i < 'hdbc) ? 8'hd0 : (i < 'hdbd) ? 8'hc0 : (i < 'hdbe) ? 8'hd0 : (i < 'hdbf) ? 8'hd8 :
|
||||
(i < 'hdc0) ? 8'hdb : (i < 'hdcf) ? 8'hc0 : (i < 'hdd0) ? 8'hd8 : (i < 'hdd7) ? 8'hc0 :
|
||||
(i < 'hdd8) ? 8'hd8 : (i < 'hddb) ? 8'hc0 : (i < 'hddc) ? 8'hd8 : (i < 'hddd) ? 8'hd0 :
|
||||
(i < 'hddf) ? 8'hd8 : (i < 'hde0) ? 8'hdd : (i < 'hde3) ? 8'hc0 : (i < 'hde4) ? 8'hd0 :
|
||||
(i < 'hde5) ? 8'hc0 : (i < 'hde7) ? 8'hd0 : (i < 'hde8) ? 8'hdc : (i < 'hde9) ? 8'hd0 :
|
||||
(i < 'hdeb) ? 8'hd8 : (i < 'hdec) ? 8'hdc : (i < 'hded) ? 8'hd8 : (i < 'hdef) ? 8'hdc :
|
||||
(i < 'hdf0) ? 8'hde : (i < 'hdf1) ? 8'hd8 : (i < 'hdf3) ? 8'hdc : (i < 'hdf4) ? 8'hde :
|
||||
(i < 'hdf5) ? 8'hdc : (i < 'hdf7) ? 8'hde : (i < 'hdf8) ? 8'hdf : (i < 'hdf9) ? 8'hde :
|
||||
(i < 'he00) ? 8'hdf : (i < 'he3f) ? 8'hc0 : (i < 'he40) ? 8'he3 : (i < 'he57) ? 8'hc0 :
|
||||
(i < 'he58) ? 8'he0 : (i < 'he5b) ? 8'hc0 : (i < 'he5c) ? 8'he0 : (i < 'he5d) ? 8'hc0 :
|
||||
(i < 'he5f) ? 8'he0 : (i < 'he60) ? 8'he1 : (i < 'he67) ? 8'hc0 : (i < 'he68) ? 8'he0 :
|
||||
(i < 'he6b) ? 8'hc0 : (i < 'he70) ? 8'he0 : (i < 'he71) ? 8'hc0 : (i < 'he7d) ? 8'he0 :
|
||||
(i < 'he7e) ? 8'he1 : (i < 'he7f) ? 8'he3 : (i < 'he80) ? 8'he7 : (i < 'he87) ? 8'hc0 :
|
||||
(i < 'he88) ? 8'he0 : (i < 'he8b) ? 8'hc0 : (i < 'he8c) ? 8'he0 : (i < 'he8d) ? 8'hc0 :
|
||||
(i < 'he90) ? 8'he0 : (i < 'he93) ? 8'hc0 : (i < 'he94) ? 8'he0 : (i < 'he95) ? 8'hc0 :
|
||||
(i < 'hebf) ? 8'he0 : (i < 'hec0) ? 8'heb : (i < 'hedb) ? 8'he0 : (i < 'hedc) ? 8'he8 :
|
||||
(i < 'hedd) ? 8'he0 : (i < 'hedf) ? 8'he8 : (i < 'hee0) ? 8'hed : (i < 'hee7) ? 8'he0 :
|
||||
(i < 'hee8) ? 8'hec : (i < 'heeb) ? 8'he0 : (i < 'heec) ? 8'hec : (i < 'heed) ? 8'he8 :
|
||||
(i < 'heef) ? 8'hec : (i < 'hef0) ? 8'hee : (i < 'hef3) ? 8'he8 : (i < 'hef5) ? 8'hec :
|
||||
(i < 'hef7) ? 8'hee : (i < 'hef8) ? 8'hef : (i < 'hef9) ? 8'hec : (i < 'hf00) ? 8'hef :
|
||||
(i < 'hf1f) ? 8'he0 : (i < 'hf20) ? 8'hf0 : (i < 'hf27) ? 8'he0 : (i < 'hf28) ? 8'hf0 :
|
||||
(i < 'hf2b) ? 8'he0 : (i < 'hf2c) ? 8'hf0 : (i < 'hf2d) ? 8'he0 : (i < 'hf30) ? 8'hf0 :
|
||||
(i < 'hf33) ? 8'he0 : (i < 'hf3f) ? 8'hf0 : (i < 'hf40) ? 8'hf3 : (i < 'hf43) ? 8'he0 :
|
||||
(i < 'hf5f) ? 8'hf0 : (i < 'hf60) ? 8'hf5 : (i < 'hf6d) ? 8'hf0 : (i < 'hf6f) ? 8'hf4 :
|
||||
(i < 'hf70) ? 8'hf6 : (i < 'hf73) ? 8'hf0 : (i < 'hf74) ? 8'hf4 : (i < 'hf75) ? 8'hf0 :
|
||||
(i < 'hf76) ? 8'hf4 : (i < 'hf77) ? 8'hf6 : (i < 'hf78) ? 8'hf7 : (i < 'hf79) ? 8'hf4 :
|
||||
(i < 'hf7b) ? 8'hf6 : (i < 'hf80) ? 8'hf7 : (i < 'hf87) ? 8'hf0 : (i < 'hf88) ? 8'hf8 :
|
||||
(i < 'hf8d) ? 8'hf0 : (i < 'hf90) ? 8'hf8 : (i < 'hf93) ? 8'hf0 : (i < 'hf94) ? 8'hf8 :
|
||||
(i < 'hf95) ? 8'hf0 : (i < 'hf9f) ? 8'hf8 : (i < 'hfa0) ? 8'hf9 : (i < 'hfaf) ? 8'hf8 :
|
||||
(i < 'hfb0) ? 8'hfa : (i < 'hfb7) ? 8'hf8 : (i < 'hfb8) ? 8'hfb : (i < 'hfb9) ? 8'hf8 :
|
||||
(i < 'hfbb) ? 8'hfa : (i < 'hfc0) ? 8'hfb : (i < 'hfc3) ? 8'hf8 : (i < 'hfc4) ? 8'hfc :
|
||||
(i < 'hfc5) ? 8'hf8 : (i < 'hfd7) ? 8'hfc : (i < 'hfd8) ? 8'hfd : (i < 'hfdb) ? 8'hfc :
|
||||
(i < 'hfe0) ? 8'hfd : (i < 'hfe2) ? 8'hfc : (i < 'hff0) ? 8'hfe : 8'hff;
|
||||
|
||||
for(i = 0; i<4096; i=i+1) wave_pst[i] =
|
||||
(i < 'h3ff) ? 8'h00 : (i < 'h400) ? 8'h1f : (i < 'h7ee) ? 8'h00 : (i < 'h7ef) ? 8'h20 :
|
||||
(i < 'h7f0) ? 8'h70 : (i < 'h7f1) ? 8'h60 : (i < 'h7f2) ? 8'h20 : (i < 'h7f7) ? 8'h70 :
|
||||
(i < 'h7fa) ? 8'h78 : (i < 'h7fc) ? 8'h7c : (i < 'h7fe) ? 8'h7e : (i < 'h800) ? 8'h7f :
|
||||
(i < 'hbfd) ? 8'h00 : (i < 'hbfe) ? 8'h08 : (i < 'hbff) ? 8'h1e : (i < 'hc00) ? 8'h3f :
|
||||
(i < 'hdf7) ? 8'h00 : (i < 'hdfe) ? 8'h80 : (i < 'hdff) ? 8'h8c : (i < 'he00) ? 8'h9f :
|
||||
(i < 'he3e) ? 8'h00 : (i < 'he40) ? 8'h80 : (i < 'he5e) ? 8'h00 : (i < 'he60) ? 8'h80 :
|
||||
(i < 'he66) ? 8'h00 : (i < 'he67) ? 8'h80 : (i < 'he6a) ? 8'h00 : (i < 'he80) ? 8'h80 :
|
||||
(i < 'he82) ? 8'h00 : (i < 'he83) ? 8'h80 : (i < 'he85) ? 8'h00 : (i < 'he89) ? 8'h80 :
|
||||
(i < 'he8a) ? 8'h00 : (i < 'heee) ? 8'h80 : (i < 'heff) ? 8'hc0 : (i < 'hf00) ? 8'hcf :
|
||||
(i < 'hf6f) ? 8'hc0 : (i < 'hf70) ? 8'he0 : (i < 'hf74) ? 8'hc0 : (i < 'hf7f) ? 8'he0 :
|
||||
(i < 'hf80) ? 8'he3 : (i < 'hfb6) ? 8'he0 : (i < 'hfda) ? 8'hf0 : (i < 'hfeb) ? 8'hf8 :
|
||||
(i < 'hff5) ? 8'hfc : (i < 'hff9) ? 8'hfe : 8'hff;
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -1,29 +1,130 @@
|
||||
|
||||
module sigma_delta_dac #(parameter MSBI=14, parameter INV=1'b1)
|
||||
(
|
||||
output reg DACout = INV, //Average Output feeding analog lowpass
|
||||
input [MSBI:0] DACin, //DAC input (excess 2**MSBI)
|
||||
input CLK,
|
||||
input RESET
|
||||
// sigmadelta.v
|
||||
// two channel second order sigma delta dac
|
||||
// taken from Minimig
|
||||
|
||||
// audio data processing
|
||||
// stereo sigma/delta bitstream modulator
|
||||
module sigma_delta_dac (
|
||||
input clk, // bus clock
|
||||
input [14:0] ldatasum, // left channel data
|
||||
input [14:0] rdatasum, // right channel data
|
||||
output reg aleft=0, // left bitstream output
|
||||
output reg aright=0 // right bitsteam output
|
||||
);
|
||||
|
||||
reg [MSBI+2:0] DeltaAdder; //Output of Delta Adder
|
||||
reg [MSBI+2:0] SigmaAdder; //Output of Sigma Adder
|
||||
reg [MSBI+2:0] SigmaLatch; //Latches output of Sigma Adder
|
||||
reg [MSBI+2:0] DeltaB; //B input of Delta Adder
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
always @(*) DeltaB = {SigmaLatch[MSBI+2], SigmaLatch[MSBI+2]} << (MSBI+1);
|
||||
always @(*) DeltaAdder = DACin + DeltaB;
|
||||
always @(*) SigmaAdder = DeltaAdder + SigmaLatch;
|
||||
// local signals
|
||||
localparam DW = 15;
|
||||
localparam CW = 2;
|
||||
localparam RW = 4;
|
||||
localparam A1W = 2;
|
||||
localparam A2W = 5;
|
||||
|
||||
always @(posedge CLK or posedge RESET) begin
|
||||
if(RESET) begin
|
||||
SigmaLatch <= 1'b1 << (MSBI+1);
|
||||
DACout <= INV;
|
||||
end else begin
|
||||
SigmaLatch <= SigmaAdder;
|
||||
DACout <= SigmaLatch[MSBI+2] ^ INV;
|
||||
end
|
||||
wire [DW+2+0 -1:0] sd_l_er0, sd_r_er0;
|
||||
reg [DW+2+0 -1:0] sd_l_er0_prev=0, sd_r_er0_prev=0;
|
||||
wire [DW+A1W+2-1:0] sd_l_aca1, sd_r_aca1;
|
||||
wire [DW+A2W+2-1:0] sd_l_aca2, sd_r_aca2;
|
||||
reg [DW+A1W+2-1:0] sd_l_ac1=0, sd_r_ac1=0;
|
||||
reg [DW+A2W+2-1:0] sd_l_ac2=0, sd_r_ac2=0;
|
||||
wire [DW+A2W+3-1:0] sd_l_quant, sd_r_quant;
|
||||
|
||||
// LPF noise LFSR
|
||||
reg [24-1:0] seed1 = 24'h654321;
|
||||
reg [19-1:0] seed2 = 19'h12345;
|
||||
reg [24-1:0] seed_sum=0, seed_prev=0, seed_out=0;
|
||||
always @ (posedge clk) begin
|
||||
if (&seed1)
|
||||
seed1 <= #1 24'h654321;
|
||||
else
|
||||
seed1 <= #1 {seed1[22:0], ~(seed1[23] ^ seed1[22] ^ seed1[21] ^ seed1[16])};
|
||||
end
|
||||
always @ (posedge clk) begin
|
||||
if (&seed2)
|
||||
seed2 <= #1 19'h12345;
|
||||
else
|
||||
seed2 <= #1 {seed2[17:0], ~(seed2[18] ^ seed2[17] ^ seed2[16] ^ seed2[13] ^ seed2[0])};
|
||||
end
|
||||
always @ (posedge clk) begin
|
||||
seed_sum <= #1 seed1 + {5'b0, seed2};
|
||||
seed_prev <= #1 seed_sum;
|
||||
seed_out <= #1 seed_sum - seed_prev;
|
||||
end
|
||||
|
||||
endmodule
|
||||
// linear interpolate
|
||||
localparam ID=4; // counter size, also 2^ID = interpolation rate
|
||||
reg [ID+0-1:0] int_cnt = 0;
|
||||
always @ (posedge clk) int_cnt <= #1 int_cnt + 'd1;
|
||||
|
||||
reg [DW+0-1:0] ldata_cur=0, ldata_prev=0;
|
||||
reg [DW+0-1:0] rdata_cur=0, rdata_prev=0;
|
||||
wire [DW+1-1:0] ldata_step, rdata_step;
|
||||
reg [DW+ID-1:0] ldata_int=0, rdata_int=0;
|
||||
wire [DW+0-1:0] ldata_int_out, rdata_int_out;
|
||||
assign ldata_step = {ldata_cur[DW-1], ldata_cur} - {ldata_prev[DW-1], ldata_prev}; // signed subtract
|
||||
assign rdata_step = {rdata_cur[DW-1], rdata_cur} - {rdata_prev[DW-1], rdata_prev}; // signed subtract
|
||||
always @ (posedge clk) begin
|
||||
if (~|int_cnt) begin
|
||||
ldata_prev <= #1 ldata_cur;
|
||||
ldata_cur <= #1 ldatasum; //{~ldatasum[DW-1], ldatasum[DW-2:0]}; // convert to offset binary, samples no longer signed!
|
||||
rdata_prev <= #1 rdata_cur;
|
||||
rdata_cur <= #1 rdatasum; //{~rdatasum[DW-1], rdatasum[DW-2:0]}; // convert to offset binary, samples no longer signed!
|
||||
ldata_int <= #1 {ldata_cur[DW-1], ldata_cur, {ID{1'b0}}};
|
||||
rdata_int <= #1 {rdata_cur[DW-1], rdata_cur, {ID{1'b0}}};
|
||||
end else begin
|
||||
ldata_int <= #1 ldata_int + {{ID{ldata_step[DW+1-1]}}, ldata_step};
|
||||
rdata_int <= #1 rdata_int + {{ID{rdata_step[DW+1-1]}}, rdata_step};
|
||||
end
|
||||
end
|
||||
assign ldata_int_out = ldata_int[DW+ID-1:ID];
|
||||
assign rdata_int_out = rdata_int[DW+ID-1:ID];
|
||||
|
||||
// input gain x3
|
||||
wire [DW+2-1:0] ldata_gain, rdata_gain;
|
||||
assign ldata_gain = {ldata_int_out[DW-1], ldata_int_out, 1'b0} + {{(2){ldata_int_out[DW-1]}}, ldata_int_out};
|
||||
assign rdata_gain = {rdata_int_out[DW-1], rdata_int_out, 1'b0} + {{(2){rdata_int_out[DW-1]}}, rdata_int_out};
|
||||
|
||||
/*
|
||||
// random dither to 15 bits
|
||||
reg [DW-1:0] ldata=0, rdata=0;
|
||||
always @ (posedge clk) begin
|
||||
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 );
|
||||
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 );
|
||||
end
|
||||
*/
|
||||
|
||||
// accumulator adders
|
||||
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;
|
||||
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;
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
// accumulators
|
||||
always @ (posedge clk) begin
|
||||
sd_l_ac1 <= #1 sd_l_aca1;
|
||||
sd_r_ac1 <= #1 sd_r_aca1;
|
||||
sd_l_ac2 <= #1 sd_l_aca2;
|
||||
sd_r_ac2 <= #1 sd_r_aca2;
|
||||
end
|
||||
|
||||
// value for quantizaton
|
||||
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]};
|
||||
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]};
|
||||
|
||||
// error feedback
|
||||
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}}};
|
||||
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}}};
|
||||
always @ (posedge clk) begin
|
||||
sd_l_er0_prev <= #1 (&sd_l_er0) ? sd_l_er0 : sd_l_er0+1;
|
||||
sd_r_er0_prev <= #1 (&sd_r_er0) ? sd_r_er0 : sd_r_er0+1;
|
||||
end
|
||||
|
||||
// output
|
||||
always @ (posedge clk) begin
|
||||
aleft <= #1 (~|ldata_gain) ? ~aleft : ~sd_l_er0[DW+2-1];
|
||||
aright <= #1 (~|rdata_gain) ? ~aright : ~sd_r_er0[DW+2-1];
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -1,20 +0,0 @@
|
||||
// 64 byte buffer for loading files
|
||||
// used to interrogate file type
|
||||
// L.C.Ashmore 17
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
module header_buffer
|
||||
(
|
||||
inout reg [7:0] header_buff [0:63]
|
||||
);
|
||||
|
||||
integer i;
|
||||
|
||||
initial begin
|
||||
for (i = 0; i < 64; i = i +1)
|
||||
header_buff [i] = 0;
|
||||
end
|
||||
endmodule
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
// memory block transfer routine
|
||||
// L.C.Ashmore feb17
|
||||
//
|
||||
// PRG T64 CRT TAP files load to intermediate buffer 0x200000 (2m)
|
||||
//
|
||||
// this routine reads 1st 16bytes to determine file type then either:
|
||||
// 1, if CRT or TAP move to 0x100000 (1m) and sets cartridge or tap attached flags
|
||||
// 2, if PRG or T64 moves directly into c64 memory map (injection)
|
||||
// T64 format pain in the arse so only basic function !!
|
||||
|
||||
module block_transfer
|
||||
(
|
||||
input clk32,
|
||||
input [31:0] addr_total_size,
|
||||
input sdram_we,
|
||||
input sdram_data_out,
|
||||
output cart_attached,
|
||||
output reg [24:0] sdram_read_addr,
|
||||
output reg [24:0] sdram_write_addr,
|
||||
inout reg [7:0] sdram_data
|
||||
);
|
||||
|
||||
localparam buffer_address2m = 'h200000;
|
||||
localparam buffer_address1m = 'h100000;
|
||||
|
||||
reg [24:0] block_addr;
|
||||
//reg [24:0] sdram_read_addr;
|
||||
//reg [24:0] sdram_write_addr;
|
||||
//reg [7:0] sdram_data;
|
||||
reg transfer_active;
|
||||
reg read_flag;
|
||||
|
||||
always @(negedge clk32)
|
||||
begin
|
||||
if (sdram_we == 1 && transfer_active && !read_flag) //sdram in read cycle - not yet read
|
||||
begin
|
||||
sdram_read_addr <= block_addr + buffer_address2m;
|
||||
sdram_data <= sdram_data_out;
|
||||
read_flag = 1;
|
||||
end
|
||||
if (sdram_we == 0 && read_flag)
|
||||
begin
|
||||
sdram_write_addr <= block_addr +buffer_address1m;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
Reference in New Issue
Block a user