Project

General

Profile

« Previous | Next » 

Revision 1499

Added by markw 2 days ago

Disable lowpass again, remembered the filter is explicit for spdif output (where it matters). Make spdif component explicitly have a port for left/right. Get all versions building again (some needed old dac for space reasons). Change default volume for adc and sio mixing for v4.5 (SHOULD not need the filtering there, testing now).

View differences:

atari_chips/pokeyv2/build.sh
"a6_bit" => 3,
"a7_bit" => 19, #use CS1
"cs1_bit" => 20, #force high
"optimisearea" => 1
"optimisearea" => 1,
"sigmadelta_implementation" => 2
},
},
"10M16SCU169C8G" =>
......
"ps2clk_bit" => 7,
"ps2dat_bit" => 8,
"ext_bits"=> 11,
"sigmadelta_implementation" => 2
},
"stereo_psg_covox_auto" =>
{
......
#"a7_bit" => 19, #use CS1
"ext_bits"=> 11,
#"cs1_bit" => 20, #force high
"sigmadelta_implementation" => 2
},
},
"10M16SCU169C8G" =>
......
"paddle_comp"=>0,
"enable_iox"=>0,
"enable_adc"=>0,
"adc_audio_detect"=>1,
"adc_fir_filter_v4"=>1,
"adc_volume"=>3,
"sio_data_volume"=>2,
"pll_v2" => 0,
"optimisearea" => 1,
},
......
"paddle_comp"=>0,
"enable_iox"=>0,
"enable_adc"=>1,
"adc_audio_detect"=>1,
"adc_fir_filter_v4"=>1,
"adc_volume"=>3,
"sio_data_volume"=>2,
"pll_v2" => 0,
"optimisearea" => 1,
},
......
"paddle_comp"=>0,
"enable_iox"=>0,
"enable_adc"=>1,
"adc_audio_detect"=>1,
"adc_fir_filter_v4"=>1,
"adc_volume"=>3,
"sio_data_volume"=>2,
"pll_v2" => 0,
"optimisearea" => 1,
},
......
"paddle_comp"=>0,
"enable_iox"=>0,
"enable_adc"=>1,
"adc_audio_detect"=>1,
"adc_fir_filter_v4"=>1,
"adc_volume"=>3,
"sio_data_volume"=>2,
"pll_v2" => 0,
"optimisearea" => 1,
},
......
"paddle_comp"=>0,
"enable_iox"=>0,
"enable_adc"=>1,
"adc_audio_detect"=>1,
"adc_fir_filter_v4"=>1,
"adc_volume"=>3,
"sio_data_volume"=>2,
"pll_v2" => 0,
"optimisearea" => 1,
},
......
},
"pokeymax_v4.5" =>
{
"10M16SCU169C8G" =>
{
"full_quad" =>
{
"enable_audout2" => 0,
"pokeys" => 4,
"enable_auto_stereo" => 1,
"enable_sid" => 1,
"enable_psg" => 1,
"enable_covox" => 1,
"enable_sample" => 1,
"enable_flash" => 1,
"enable_spdif" => 1,
"enable_ps2" => 1,
"flash_addr_bits" => 17,
"sid_wave_base" => 79872, #"to_integer(unsigned(x\"13800\"))",
"fancy_switch_bit" => 1,
"a4_bit" => 2,
"a5_bit" => 3,
"a6_bit" => 4,
"a7_bit" => 5,
"ps2clk_bit" => 6,
"ps2dat_bit" => 7,
"gtia_audio_bit" => 8,
"spdif_bit" => 10,
"ext_bits"=> 10,
"paddle_lvds"=>1,
"paddle_comp"=>0,
"enable_iox"=>0,
"enable_adc"=>1,
"adc_volume"=>1,
"sio_data_volume"=>0,
"pll_v2" => 0,
"optimisearea" => 1,
},
"mono" =>
{
"enable_audout2" => 0,
"pokeys" => 1,
"enable_auto_stereo" => 1,
"enable_sid" => 0,
"enable_psg" => 0,
"enable_covox" => 0,
"enable_sample" => 0,
"enable_flash" => 1,
"flash_addr_bits" => 17,
"a4_bit" => 2,
"a5_bit" => 3,
"a6_bit" => 4,
"a7_bit" => 5,
"fancy_switch_bit" => 1,
"ps2clk_bit" => 6,
"ps2dat_bit" => 7,
"gtia_audio_bit" => 8,
"spdif_bit" => 10,
"ext_bits"=> 10,
"paddle_lvds"=>1,
"paddle_comp"=>0,
"enable_iox"=>0,
"enable_adc"=>1,
"adc_volume"=>1,
"sio_data_volume"=>0,
"pll_v2" => 0,
"optimisearea" => 1,
},
},
"10M08SCU169C8G" =>
{
"full_stereo_sample" =>
......
"enable_flash" => 1,
"enable_spdif" => 0,
"enable_ps2" => 0,
"fancy_switch_bit" => 1,
"a4_bit" => 2,
"a5_bit" => 3,
"a6_bit" => 4,
......
"ps2clk_bit" => 6,
"ps2dat_bit" => 7,
"gtia_audio_bit" => 8,
"fancy_switch_bit" => 9,
"spdif_bit" => 1,
"spdif_bit" => 10,
"ext_bits"=> 10,
"paddle_lvds"=>1,
"paddle_comp"=>0,
"enable_iox"=>0,
"enable_adc"=>0,
"adc_volume"=>1,
"sio_data_volume"=>0,
"pll_v2" => 0,
"optimisearea" => 1,
},
......
"enable_flash" => 1,
"enable_spdif" => 1,
"enable_ps2" => 0,
"fancy_switch_bit" => 1,
"a4_bit" => 2,
"a5_bit" => 3,
"a6_bit" => 4,
......
#"gtia_audio_bit" => 9, PASS
#"gtia_audio_bit" => 5, PASS
"gtia_audio_bit" => 8,
"fancy_switch_bit" => 9,
"spdif_bit" => 1,
"spdif_bit" => 10,
"ext_bits"=> 10,
"paddle_lvds"=>1,
"paddle_comp"=>0,
"enable_iox"=>0,
"enable_adc"=>1,
"adc_volume"=>1,
"sio_data_volume"=>0,
"pll_v2" => 0,
"optimisearea" => 1,
},
......
"enable_covox" => 0,
"enable_sample" => 0,
"enable_flash" => 1,
"fancy_switch_bit" => 1,
"a4_bit" => 2,
"a5_bit" => 3,
"a6_bit" => 4,
......
"ps2clk_bit" => 6,
"ps2dat_bit" => 7,
"gtia_audio_bit" => 8,
"fancy_switch_bit" => 9,
"spdif_bit" => 1,
"spdif_bit" => 10,
"ext_bits"=> 10,
"paddle_lvds"=>1,
"paddle_comp"=>0,
"enable_iox"=>0,
"enable_adc"=>1,
"adc_volume"=>1,
"sio_data_volume"=>0,
"pll_v2" => 0,
"optimisearea" => 1,
},
......
next unless ($dir =~ /$wanted_variant/);
}
print "Building $versioncode $name of $typeboard into $dir\n";
`rm -f init*.bin`;
my $sio_data_volume = 2;
my $adc_volume = 0;
if (exists $spec->{"adc_volume"})
{
$adc_volume = $spec->{"adc_volume"}
}
if (exists $spec->{"sio_data_volume"})
{
$adc_volume = $spec->{"sio_data_volume"}
}
`./init adc_volume=$adc_volume sio_data_volume=$sio_data_volume`;
`rm -f init*.hex`;
`./makehexfiles`;
`rm -rf $dir`;
mkdir $dir;
......
#The sof file is compressed
#Reason being that we have a user flash area (UFM) and a config flash area (CFM)
#We steal some of the CFM space for sid wave tables but it needs to be empty
print("quartus_cpf --convert ../convert_secure_${type}_${needs_sid_waves}.cof");
`quartus_cpf --convert ../convert_secure_${type}_${needs_sid_waves}.cof`;
if (int($fpgasize)>=8 and $needs_sid_waves) #We only patch the larger ones, the others do not have space...
atari_chips/pokeyv2/convert_secure_pokeymax_0.cof
<verify_protect>1</verify_protect>
<epof>0</epof>
<ufm_source>2</ufm_source>
<ufm_filepath>../init_0.hex</ufm_filepath>
<ufm_filepath>./init_0.hex</ufm_filepath>
</MAX10_device_options>
<advanced_options>
<ignore_epcs_id_check>1</ignore_epcs_id_check>
atari_chips/pokeyv2/convert_secure_pokeymax_1.cof
<verify_protect>1</verify_protect>
<epof>0</epof>
<ufm_source>2</ufm_source>
<ufm_filepath>../init_1.hex</ufm_filepath>
<ufm_filepath>./init_1.hex</ufm_filepath>
</MAX10_device_options>
<advanced_options>
<ignore_epcs_id_check>1</ignore_epcs_id_check>
atari_chips/pokeyv2/convert_secure_sidmax_1.cof
<verify_protect>1</verify_protect>
<epof>0</epof>
<ufm_source>2</ufm_source>
<ufm_filepath>../init_1.hex</ufm_filepath>
<ufm_filepath>./init_1.hex</ufm_filepath>
</MAX10_device_options>
<advanced_options>
<ignore_epcs_id_check>1</ignore_epcs_id_check>
atari_chips/pokeyv2/init.c
#include "stdio.h"
#include "stdlib.h"
#include <math.h>
#include <string.h>
int ima_step_table[89] = {
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
......
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
};
int main(void)
int main(int argc, char * argv[])
{
/*
SATURATE_NEXT <= flash_do(0));
......
int irq_en = 0;
int detect_right = 1;
int pal = 1;
int sio_data_volume = 2;
int adc_volume = 3;
int sio_data_volume = 0;
int adc_volume = 0;
int post_divide = 0b10100000;
int gtia_enable = 0b1100;
int psg_freq = 0;
int psg_stereomode = 1;
int psg_envelope16 = 0;
for (i=1;i!=argc;++i)
{
int len = strlen(argv[i]);
int eq = -1;
for (int j=0;j!=len;++j)
{
if (argv[i][j]=='=')
{
eq = j;
break;
}
}
if (eq>=0)
{
if (strncmp(argv[i],"adc_volume",eq)==0)
{
adc_volume = atoi(argv[i]+eq+1);
printf("adc_volume:%d\n",adc_volume);
}
else if (strncmp(argv[i],"sio_data_volume",eq)==0)
{
sio_data_volume = atoi(argv[i]+eq+1);
printf("sio_data_volume:%d\n",sio_data_volume);
}
}
}
buffer[0] |= (saturate&3)<<0;
buffer[0] |= (channel_mode&1)<<2;
buffer[0] |= (irq_en&1)<<3;
buffer[0] |= (detect_right&1)<<4;
buffer[0] |= (pal&1)<<5;
int post_divide = 0b10100000;
buffer[1] |= (post_divide&0xff)<<0;
int gtia_enable = 0b1100;
buffer[2] |= (gtia_enable&0xf)<<0;
buffer[2] |= (adc_volume&0x3)<<4;
buffer[2] |= (sio_data_volume&0x3)<<6;
int psg_freq = 0;
int psg_stereomode = 1;
int psg_envelope16 = 0;
buffer[3] |= (psg_freq&3)<<0;
buffer[3] |= (psg_stereomode&3)<<2;
buffer[3] |= (psg_envelope16&1)<<4;
atari_chips/pokeyv2/pokeymax.vhd
GENERIC
(
pokeys : integer := 1; -- 1-4
lowpass : integer := 1; -- 0=lowpass off, 1=lowpass on (leave on except if there is no space! Low impact...)
lowpass : integer := 0; -- 0=lowpass off, 1=lowpass on (only needed for hdmi/spdif and we already have a local filter there)
enable_auto_stereo : integer := 0; -- 1=auto detect a4 => not toggling => mono
fancy_switch_bit : integer := 20; -- 0=ext is low => mono
......
adc_audio_detect : integer := 0; -- Detect 0 crossing/amplitude etc, otherwise silence
adc_fir_filter_v4 : integer := 0; -- Filter out interference from keyboard scan etc
sigmadelta_implementation : integer := 4; -- 4 is dithered 2nd order (recommended if it fits), 2 is 2nd order without dithering
ext_bits : integer := 3;
pll_v2 : integer := 1;
......
signal MHZ2_ENABLE : std_logic;
-- spdif
signal spdif_mux : std_logic_vector(15 downto 0);
signal spdif_left : std_logic;
signal spdif_out : std_logic;
signal CLK6144 : std_logic; --spdif
signal AUDIO_2_FILTERED : unsigned(15 downto 0);
......
dac_0 : entity work.filtered_sigmadelta --pin37
GENERIC MAP
(
IMPLEMENTATION => 4,
IMPLEMENTATION => sigmadelta_implementation,
LOWPASS => lowpass,
LFSR_SEED => x"ACE2"
)
......
dac_1 : entity work.filtered_sigmadelta
GENERIC MAP
(
IMPLEMENTATION => 4,
IMPLEMENTATION => sigmadelta_implementation,
LOWPASS => lowpass,
LFSR_SEED => x"1D2B"
)
......
dac_2 : entity work.filtered_sigmadelta
GENERIC MAP
(
IMPLEMENTATION => 4,
IMPLEMENTATION => sigmadelta_implementation,
LOWPASS => lowpass,
LFSR_SEED => x"BEEF"
)
......
dac_3 : entity work.filtered_sigmadelta
GENERIC MAP
(
IMPLEMENTATION => 4,
IMPLEMENTATION => sigmadelta_implementation,
LOWPASS => lowpass,
LFSR_SEED => x"5A3C"
)
......
-- Digital audio output
spdif_on : if enable_spdif=1 generate
-- todo: clock domain crossing!
spdif_mux <= std_logic_vector(audio_2_filtered) when spdif_left='1'
else std_logic_vector(audio_3_filtered);
filter_left : entity work.simple_low_pass_filter
PORT MAP
(
......
AUDIO_OUT => audio_3_filtered
);
---- todo: clock domain crossing!
spdif : entity work.spdif_transmitter
port map(
bit_clock => CLK6144, -- 128x Fsample (6.144MHz for 48K samplerate)
data_in(23) => not(spdif_mux(15)),
data_in(22 downto 8) => spdif_mux(14 downto 0),
data_in(7 downto 0) => (others=>'0'),
address_out => spdif_left,
left_in(23) => not(audio_2_filtered(15)),
left_in(22 downto 8) => std_logic_vector(audio_2_filtered(14 downto 0)),
left_in(7 downto 0) => (others=>'0'),
right_in(23) => not(audio_3_filtered(15)),
right_in(22 downto 8) => std_logic_vector(audio_3_filtered(14 downto 0)),
right_in(7 downto 0) => (others=>'0'),
spdif_out => spdif_out
);
......
end generate fir_on;
fir_off : if adc_fir_filter_v4=0 generate
adc_out_signed <= adc_in_signed
adc_out_signed <= adc_in_signed;
end generate fir_off;
SIO_AUDIO <= unsigned(not(adc_use_reg(15))&adc_use_reg(14 downto 0));
......
--1->pin37
AUD(1) <= AUDIO_0_SIGMADELTA when CHANNEL_EN_REG(0)='1' else '0';
AUD(1) <= AUDIO_0_SIGMADELTA when CHANNEL_EN_REG(0)='1' else '0'; --L (internal)
-- ext AUD pins:
AUD(2) <= AUDIO_1_SIGMADELTA when CHANNEL_EN_REG(1)='1' else '0';
AUD(3) <= AUDIO_2_SIGMADELTA when CHANNEL_EN_REG(2)='1' else '0';
AUD(4) <= AUDIO_3_SIGMADELTA when CHANNEL_EN_REG(3)='1' else '0';
AUD(2) <= AUDIO_1_SIGMADELTA when CHANNEL_EN_REG(1)='1' else '0'; --R (external version of internal, if present on board)
AUD(3) <= AUDIO_2_SIGMADELTA when CHANNEL_EN_REG(2)='1' else '0'; --L
AUD(4) <= AUDIO_3_SIGMADELTA when CHANNEL_EN_REG(3)='1' else '0'; --R
IRQ <= '0' when (IRQ_EN_REG='1' and (and_reduce(POKEY_IRQ)='0')) or (IRQ_EN_REG='0' and POKEY_IRQ(0)='0') or (SAMPLE_IRQ='1') else 'Z';
atari_chips/pokeyv2/pokeymaxv1.qsf
set_instance_assignment -name IO_STANDARD "3.3 V SCHMITT TRIGGER" -to BCLK
set_global_assignment -name OPTIMIZATION_MODE BALANCED
set_global_assignment -name VHDL_FILE audio_signal_detector.vhd
set_global_assignment -name VHDL_FILE flash_controller.vhd
set_global_assignment -name VHDL_FILE stereo_detect.vhd
set_global_assignment -name VHDL_FILE iox_glue.vhdl
......
set_global_assignment -name SDC_FILE pokeymax.sdc
set_global_assignment -name VHDL_FILE complete_address_decoder.vhdl
set_global_assignment -name VHDL_FILE syncreset_enable_divider.vhd
set_global_assignment -name VHDL_FILE enable_divider.vhdl
set_global_assignment -name VHDL_FILE delay_line.vhdl
set_global_assignment -name VHDL_FILE wide_delay_line.vhdl
set_global_assignment -name VHDL_FILE latch_delay_line.vhdl
......
set_global_assignment -name VHDL_FILE sigmadelta_2ndorder.vhd
set_global_assignment -name VHDL_FILE sigmadelta_2ndorder_dither.vhd
set_global_assignment -name VHDL_FILE filtered_sigmadelta.vhd
set_global_assignment -name VHDL_FILE fir_filter.vhdl
set_global_assignment -name VHDL_FILE fir_rom.vhdl
set_global_assignment -name VHDL_FILE mult_infer.vhdl
set_global_assignment -name VHDL_FILE generic_ram_infer.vhdl
set_global_assignment -name VHDL_FILE simple_low_pass_filter.vhdl
......
set_global_assignment -name QIP_FILE int_osc/synthesis/int_osc.qip
set_global_assignment -name QIP_FILE pll.qip
set_global_assignment -name QIP_FILE flash/synthesis/flash.qip
set_global_assignment -name QIP_FILE fir_sample_buffer.qip
set_global_assignment -name QIP_FILE fir_buffer.qip
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
atari_chips/pokeyv2/pokeymaxv1.vhd
GENERIC
(
pokeys : integer := 1; -- 1-4
lowpass : integer := 0; -- 0=lowpass off, 1=lowpass on (leave on except if there is no space! Low impact...)
lowpass : integer := 0; -- 0=lowpass off, 1=lowpass on (only needed for hdmi/spdif and we already have a local filter there)
enable_auto_stereo : integer := 0; -- 1=auto detect a4 => not toggling => mono
fancy_switch_bit : integer := 20; -- 0=ext is low => mono
......
ps2clk_bit : integer := 0;
ps2dat_bit : integer := 0;
adc_audio_detect : integer := 0; -- Detect 0 crossing/amplitude etc, otherwise silence
adc_fir_filter_v4 : integer := 0; -- Filter out interference from keyboard scan etc
ext_bits : integer := 3;
pll_v2 : integer := 1;
......
END pokeymax;
ARCHITECTURE vhdl OF pokeymax IS
component sigma_delta_adc is
port (
clk : in std_logic;
rst : in std_logic;
adc_lvds_pin : in std_logic;
adc_fb_pin : out std_logic;
adc_output : out std_logic_vector(19 downto 0);
adc_valid : out std_logic
);
end component;
component int_osc is
port (
clkout : out std_logic; -- clkout.clk
......
signal CLK116 : std_logic;
signal CLK106 : std_logic;
signal RESET_N : std_logic;
signal PLL_LOCKED : std_logic;
signal ENABLE_CYCLE : std_logic;
signal ENABLE_DOUBLE_CYCLE : std_logic;
......
signal SIO_TXD : std_logic;
signal SIO_RXD : std_logic;
signal SIO_RXD_SYNC : std_logic;
signal SIO_RXD_ADC : std_logic;
signal POKEY_IRQ : std_logic_vector(3 downto 0);
......
signal SATURATE_REG : std_logic;
signal POST_DIVIDE_REG : std_logic_vector(7 downto 0);
signal GTIA_ENABLE_REG : std_logic_vector(3 downto 0);
signal ADC_VOLUME_REG : std_logic_vector(1 downto 0);
signal SIO_DATA_VOLUME_REG : std_logic_vector(1 downto 0);
signal VERSION_LOC_REG : std_logic_vector(2 downto 0);
signal PAL_REG : std_logic;
......
signal SATURATE_NEXT : std_logic;
signal POST_DIVIDE_NEXT : std_logic_vector(7 downto 0);
signal GTIA_ENABLE_NEXT : std_logic_vector(3 downto 0);
signal ADC_VOLUME_NEXT : std_logic_vector(1 downto 0);
signal SIO_DATA_VOLUME_NEXT : std_logic_vector(1 downto 0);
signal VERSION_LOC_NEXT : std_logic_vector(2 downto 0);
signal PAL_NEXT : std_logic;
......
signal MHZ2_ENABLE : std_logic;
-- spdif
signal spdif_mux : std_logic_vector(15 downto 0);
signal spdif_right : std_logic;
signal spdif_out : std_logic;
signal CLK6144 : std_logic; --spdif
signal AUDIO_2_FILTERED : unsigned(15 downto 0);
......
signal PS2DAT : std_logic;
-- adc
signal sum_reg : unsigned(7 downto 0);
signal sum_next : unsigned(7 downto 0);
signal CLK49152 : std_logic;
signal sample_reg : unsigned(7 downto 0);
signal sample_next : unsigned(7 downto 0);
signal adc_reg : signed(15 downto 0);
signal adc_next : signed(15 downto 0);
signal toggle_reg : std_logic_vector(255 downto 0);
signal toggle_next : std_logic_vector(255 downto 0);
signal adc_use_reg : signed(15 downto 0);
signal adc_use_next : signed(15 downto 0);
signal ADC_FILTERED1 : unsigned(15 downto 0);
signal ADC_FILTERED2 : unsigned(15 downto 0);
signal adc_frozen_reg : signed(15 downto 0);
signal adc_frozen_next : signed(15 downto 0);
signal sio_noise : signed(15 downto 0);
signal adc_in_signed : signed(15 downto 0);
signal adc_out_signed : signed(15 downto 0);
signal adc_enabled : std_logic;
signal adc_valid : std_logic;
signal adc_output : std_logic_vector(19 downto 0);
signal adc_lvds_pin : std_logic;
signal adc_fb_pin : std_logic;
signal fir_data_request :std_logic;
signal fir_data_address :std_logic_vector(9 downto 0);
signal fir_data_ready :std_logic;
signal SIO_AUDIO : unsigned(15 downto 0);
-- paddles
signal PADDLE_ADJ : std_logic_vector(7 downto 0);
......
flash_req7_addr(12 downto 9) => (others=>'0'),
flash_req7_addr(8 downto 0) => "11"&SATURATE_REG&POKEY_PROFILE_ADDR, --TODO + init.bin
flash_req8_addr(12 downto 12) => (others=>'0'),
flash_req8_addr(11 downto 0) => "11"&FIR_DATA_ADDRESS,
flash_req_request(0) => CPU_FLASH_REQUEST_REG,
flash_req_request(1) => CONFIG_FLASH_REQUEST,
flash_req_request(2) => ADPCM_STEP_REQUEST,
......
flash_req_request(4) => SID_FLASH2_ROMREQUEST,
flash_req_request(5) => PSG_PROFILE_REQUEST,
flash_req_request(6) => POKEY_PROFILE_REQUEST,
flash_req_request(7 downto 7) => (others=>'0'),
flash_req_request(7) => FIR_DATA_REQUEST,
flash_req_complete(7 downto 0) => open,
flash_req_complete_slow(0) => CPU_FLASH_COMPLETE,
......
flash_req_complete_slow(4) => SID_FLASH2_ROMREADY,
flash_req_complete_slow(5) => PSG_PROFILE_READY,
flash_req_complete_slow(6) => POKEY_PROFILE_READY,
flash_req_complete_slow(7 downto 7) => open,
flash_req_complete_slow(7) => FIR_DATA_READY,
flash_data_out_slow => flash_do_slow
);
......
c0 => CLK, --56 ish
c1 => CLK116, --113ish
c2 => CLK106, --106ish
locked => RESET_N);
locked => PLL_LOCKED);
CLK49152 <= '0';
end generate;
pll_v3_inst : if pll_v2=0 generate
pll_inst : pllv3
PORT MAP(inclk0 => CLK0, --49.192 (50 on prototype)
c0 => CLK, --49.192
c1 => CLK116, --113ish
c0 => CLK, --56ish
c1 => CLK116, --56ish
c2 => CLK106, --106ish
c3 => CLK6144, --6.44MHz
locked => RESET_N);
locked => PLL_LOCKED);
CLK49152 <= CLK0;
end generate;
pll_sync : entity work.pll_reset_sync
PORT MAP(CLK => CLK116,
PLL_LOCKED => PLL_LOCKED,
RESET_N => RESET_N);
AIN(3 downto 0) <= A;
AIN(7) <= EXT_INT(a7_bit);
......
end if;
POST_DIVIDE_REG <= "10100000"; -- 1/2 5v, 3/4 1v
GTIA_ENABLE_REG <= "1100"; -- external only
ADC_VOLUME_REG <= "11"; -- 0=silent,1=1x,2=2x,3=4x
SIO_DATA_VOLUME_REG <= "10"; -- 0=silent,1=quieter,2=normal,3=louder
CONFIG_ENABLE_REG <= '0';
VERSION_LOC_REG <= (others=>'0');
PAL_REG <= '1';
......
SATURATE_REG <= SATURATE_NEXT;
POST_DIVIDE_REG <= POST_DIVIDE_NEXT;
GTIA_ENABLE_REG <= GTIA_ENABLE_NEXT;
ADC_VOLUME_REG <= ADC_VOLUME_NEXT;
SIO_DATA_VOLUME_REG <= SIO_DATA_VOLUME_NEXT;
CONFIG_ENABLE_REG <= CONFIG_ENABLE_NEXT;
VERSION_LOC_REG <= VERSION_LOC_NEXT;
PAL_REG <= PAL_NEXT;
......
CONFIG_ENABLE_REG,
POST_DIVIDE_REG,
GTIA_ENABLE_REG,
ADC_VOLUME_REG,
SIO_DATA_VOLUME_REG,
VERSION_LOC_REG,
PSG_FREQ_REG,
PSG_STEREOMODE_REG,
......
POST_DIVIDE_NEXT <= POST_DIVIDE_REG;
GTIA_ENABLE_NEXT <= GTIA_ENABLE_REG;
ADC_VOLUME_NEXT <= ADC_VOLUME_REG;
SIO_DATA_VOLUME_NEXT <= SIO_DATA_VOLUME_REG;
CONFIG_ENABLE_NEXT <= CONFIG_ENABLE_REG;
......
-- 6-7 reserved
POST_DIVIDE_NEXT <= flash_do_slow(15 downto 8);
GTIA_ENABLE_NEXT <= flash_do_slow(19 downto 16);
-- 23 downto 20 reserved
ADC_VOLUME_NEXT <= flash_do_slow(21 downto 20);
SIO_DATA_VOLUME_NEXT <= flash_do_slow(23 downto 22);
PSG_FREQ_NEXT <= flash_do_slow(25 downto 24);
PSG_STEREOMODE_NEXT <= flash_do_slow(27 downto 26);
PSG_ENVELOPE16_NEXT <= flash_do_slow(28);
......
if (addr_decoded4(3)='1') then
GTIA_ENABLE_NEXT <= WRITE_DATA(3 downto 0);
ADC_VOLUME_NEXT <= WRITE_DATA(5 downto 4);
SIO_DATA_VOLUME_NEXT <= WRITE_DATA(7 downto 6);
end if;
if (addr_decoded4(4)='1') then
......
if (addr_decoded4(3)='1') then
CONFIG_DO <= (others=>'0');
CONFIG_DO(3 downto 0) <= GTIA_ENABLE_REG;
--CONFIG_DO(7 downto 4) <= SIO_ENABLE_REG; -- if we implement
if (enable_adc=1) then -- Should allow optimiser to remove since nothing else reads it
CONFIG_DO(5 downto 4) <= ADC_VOLUME_REG;
end if;
CONFIG_DO(7 downto 6) <= SIO_DATA_VOLUME_REG;
end if;
if (addr_decoded4(4)='1') then
......
CH9 => unsigned(PSG_AUDIO(1)),
CHA(14 downto 0) => (others=>'0'),
CHA(15) => GTIA_AUDIO,
CHB => ADC_FILTERED2,
CHB => SIO_AUDIO,
AUDIO_0_UNSIGNED => AUDIO_0_UNSIGNED,
AUDIO_1_UNSIGNED => AUDIO_1_UNSIGNED,
......
dac_0 : entity work.filtered_sigmadelta --pin37
GENERIC MAP
(
IMPLEMENTATION => 2,
LOWPASS => lowpass
IMPLEMENTATION => 4,
LOWPASS => lowpass,
LFSR_SEED => x"ACE2"
)
port map
(
......
dac_1 : entity work.filtered_sigmadelta
GENERIC MAP
(
IMPLEMENTATION => 2,
LOWPASS => lowpass
IMPLEMENTATION => 4,
LOWPASS => lowpass,
LFSR_SEED => x"1D2B"
)
port map
(
......
dac_2 : entity work.filtered_sigmadelta
GENERIC MAP
(
IMPLEMENTATION => 2,
LOWPASS => lowpass
IMPLEMENTATION => 4,
LOWPASS => lowpass,
LFSR_SEED => x"BEEF"
)
port map
(
......
dac_3 : entity work.filtered_sigmadelta
GENERIC MAP
(
IMPLEMENTATION => 2,
LOWPASS => lowpass
IMPLEMENTATION => 4,
LOWPASS => lowpass,
LFSR_SEED => x"5A3C"
)
port map
(
......
-- Digital audio output
spdif_on : if enable_spdif=1 generate
-- todo: clock domain crossing!
spdif_mux <= std_logic_vector(audio_2_filtered) when spdif_right='0'
else std_logic_vector(audio_3_filtered);
filter_left : entity work.simple_low_pass_filter
PORT MAP
(
......
AUDIO_OUT => audio_3_filtered
);
---- todo: clock domain crossing!
spdif : entity work.spdif_transmitter
port map(
bit_clock => CLK6144, -- 128x Fsample (6.144MHz for 48K samplerate)
data_in(23 downto 8) => spdif_mux,
data_in(7 downto 0) => (others=>'0'),
address_out => spdif_right,
left_in(23) => not(audio_2_filtered(15)),
left_in(22 downto 8) => std_logic_vector(audio_2_filtered(14 downto 0)),
left_in(7 downto 0) => (others=>'0'),
right_in(23) => not(audio_3_filtered(15)),
right_in(22 downto 8) => std_logic_vector(audio_3_filtered(14 downto 0)),
right_in(7 downto 0) => (others=>'0'),
spdif_out => spdif_out
);
......
-- drive keyboard lines
iox_on : if enable_iox=1 generate
i2c_master0 : entity work.i2c_master
generic map(input_clk=>58_000_000, bus_clk=>2_000_000)
generic map(input_clk=>58_000_000, bus_clk=>2_800_000)
port map(
clk=>clk,
reset_n=>reset_n,
......
iox_off : if enable_iox=0 generate
iox_keyboard_response <= KR2&KR1;
-- k(0) <= '0' when keyboard_scan(0)='0' else 'Z';
-- k(1) <= '0' when keyboard_scan(1)='0' else 'Z';
-- k(2) <= '0' when keyboard_scan(2)='0' else 'Z';
-- k(3) <= '0' when keyboard_scan(3)='0' else 'Z';
-- k(4) <= '0' when keyboard_scan(4)='0' else 'Z';
-- k(5) <= '0' when keyboard_scan(5)='0' else 'Z';
k <= keyboard_scan;
end generate iox_off;
......
KEYBOARD_RESPONSE <= IOX_KEYBOARD_RESPONSE;
end generate ps2_off;
synchronizer_SIO : entity work.synchronizer
port map (clk=>CLK49152, raw=>SID, sync=>SIO_RXD_ADC);
adc_on : if enable_adc=1 generate
-- Proper ADC for SIO/PBI audio in
sdelta : sigma_delta_adc
port map(
clk=>CLK49152,
rst=>not(reset_n),
adc_lvds_pin => adc_lvds_pin,
adc_fb_pin => adc_fb_pin,
adc_output => adc_output,
adc_valid => adc_valid
);
-- adc_valid <= '1';
-- adc_output <= x"abcd";
-- Simple ADC for SIO/PBI audio in
process(clk,reset_n)
process(CLK49152,reset_n)
begin
if (reset_n='0') then
toggle_reg <= (others=>'0');
sum_reg <= (others=>'0');
sample_reg <= (others=>'0');
elsif (clk'event and clk='1') then
toggle_reg <= toggle_next;
sum_reg <= sum_next;
sample_reg <= sample_next;
adc_reg <= (others=>'0');
adc_use_reg <= (others=>'0');
adc_frozen_reg <= (others=>'0');
elsif (CLK49152'event and CLK49152='1') then
adc_reg <= adc_next;
adc_use_reg <= adc_use_next;
adc_frozen_reg <= adc_frozen_next;
end if;
end process;
lvds_tx0: lvds_tx
port map(
tx_in(0) => toggle_reg(0),
tx_in(0) => adc_fb_pin,
tx_out(0) => ADC_TX_P
);
lvds_rx0: lvds_rx
port map(
data(0) => ADC_RX_P,
clock => CLK,
q(0) => toggle_next(0)
clock => CLK49152,
q(0) => adc_lvds_pin
);
toggle_next(255 downto 1) <= toggle_reg(254 downto 0);
adcfilter : entity work.simple_low_pass_filter
adc_in_signed <= adc_reg; --signed(not(adc_use_reg(15))&adc_use_reg(14 downto 0));
--adc_in_signed <= signed(not(adc_use_reg(15))&adc_use_reg(14 downto 0));
--adc_in_signed <= to_signed(1024,16);
fir_on : if adc_fir_filter_v4=1 generate
adcfirfilter : entity work.fir_filter
GENERIC MAP
(
filter_len => 2032
)
PORT MAP
(
CLK => CLK,
AUDIO_IN => not(sample_reg(7)&sample_reg(6 downto 0))&"00000000",
SAMPLE_IN => ENABLE_CYCLE,
AUDIO_OUT => ADC_FILTERED1
);
FILTER_CLK => CLK49152,
RESET_N => RESET_N,
SAMPLE_ENABLE => adc_valid,
SAMPLE_DATA => adc_in_signed,
SAMPLE_OUT => adc_out_signed,
adcfilter2 : entity work.simple_low_pass_filter
PORT MAP
(
CLK => CLK,
AUDIO_IN => ADC_FILTERED1,
SAMPLE_IN => ENABLE_CYCLE,
AUDIO_OUT => ADC_FILTERED2
FLASH_CLK => CLK,
FLASH_REQUEST => FIR_DATA_REQUEST,
FLASH_ADDRESS => FIR_DATA_ADDRESS,
FLASH_DATA => flash_do_slow,
FLASH_READY => FIR_DATA_READY
);
end generate fir_on;
process(sum_reg,sample_reg,toggle_reg)
fir_off : if adc_fir_filter_v4=0 generate
adc_out_signed <= adc_in_signed;
end generate fir_off;
SIO_AUDIO <= unsigned(not(adc_use_reg(15))&adc_use_reg(14 downto 0));
process(adc_reg,adc_output,adc_valid,ADC_VOLUME_REG)
variable adc_shrunk : signed(19 downto 0);
begin
sum_next <= sum_reg;
sample_next <= sample_reg;
adc_next <= adc_reg;
if (toggle_reg(255)='1' and toggle_reg(0)='0') then
sum_next <= sum_reg -1;
elsif (toggle_reg(255)='0' and toggle_reg(0)='1') then
sum_next <= sum_reg +1;
if (adc_valid='1') then
adc_shrunk := (signed(not(adc_output(19)) & adc_output(18 downto 0)));
case ADC_VOLUME_REG is
when "01" =>
adc_next <= adc_shrunk(19 downto (19-16+1)); --*1
when "10" =>
adc_next <= adc_shrunk(18 downto (18-16+1)); --*2
when "11" =>
adc_next <= adc_shrunk(17 downto (17-16+1)); --*4
when others =>
adc_next <= (others=>'0');
end case;
end if;
end process;
sample_next <= sum_reg;
audio_detect_on : if adc_audio_detect=1 generate
audio_signal_detector1 : work.audio_signal_detector
port map(clk=>CLK49152,reset_n=>reset_n,audio=>adc_in_signed,sample=>adc_valid,volume=>adc_volume_reg,detect_out=>adc_enabled);
end generate audio_detect_on;
audio_detect_off : if adc_audio_detect=0 generate
adc_enabled <= '1';
end generate audio_detect_off;
process(adc_use_reg,adc_frozen_reg,adc_enabled,adc_out_signed,sio_noise)
begin
adc_frozen_next <= adc_frozen_reg;
adc_use_next <= adc_frozen_reg xor sio_noise;
if (adc_enabled='1') then
adc_frozen_next <= adc_out_signed;
end if;
end process;
process(SIO_RXD_ADC,SIO_DATA_VOLUME_REG)
begin
sio_noise <= (others=>'0');
case SIO_DATA_VOLUME_REG is
when "01" =>
sio_noise(10) <= not(SIO_RXD_ADC);
when "10" =>
sio_noise(11) <= not(SIO_RXD_ADC);
when "11" =>
sio_noise(12) <= not(SIO_RXD_ADC);
when others =>
end case;
end process;
end generate adc_on;
adc_off : if enable_adc=0 generate
ADC_FILTERED2(15 downto 12) <= (others=>'0');
ADC_FILTERED2(11) <= SIO_RXD_SYNC;
ADC_FILTERED2(10 downto 0) <= (others=>'0');
process(SIO_DATA_VOLUME_REG)
begin
SIO_AUDIO(15 downto 0) <= (others=>'0');
case SIO_DATA_VOLUME_REG is
when "01" =>
SIO_AUDIO(10) <= SIO_RXD_ADC;
when "10" =>
SIO_AUDIO(11) <= SIO_RXD_ADC;
when "11" =>
SIO_AUDIO(12) <= SIO_RXD_ADC;
when others =>
end case;
end process;
end generate adc_off;
paddle_lvds_on : if paddle_lvds=1 generate
......
SOD <= '0' when SIO_TXD='0' else 'Z';
SIO_RXD <= SID;
synchronizer_SIO : entity work.synchronizer
port map (clk=>clk, raw=>SID, sync=>SIO_RXD_SYNC);
--1->pin37
atari_chips/pokeyv2/pokeymaxv3.qsf
set_location_assignment PIN_M2 -to POTRESET_N #POTRESET - M2
set_location_assignment PIN_C11 -to AUD[1] #AUD1 - C11
set_location_assignment PIN_D11 -to AUD[3] #AUD3 - D11
set_location_assignment PIN_D11 -to AUD[3] #AUD3 - D11 - L
set_location_assignment PIN_C12 -to AUD[2] #AUD2 - C12
set_location_assignment PIN_D12 -to AUD[4] #AUD4 - D12
set_location_assignment PIN_D12 -to AUD[4] #AUD4 - D12 - R
set_location_assignment PIN_M3 -to IOX_RST #IOX_RST - M3
set_location_assignment PIN_M4 -to IOX_SDA #IOX_SDA - M4
......
set_location_assignment PIN_M9 -to EXT[4] #LVLB0 EXT4 - M9
set_location_assignment PIN_M10 -to EXT[5] #LVLB1 EXT5 - M10
set_location_assignment PIN_N10 -to EXT[6] #LVLB2 EXT6 - N10
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to EXT[6]
set_location_assignment PIN_M11 -to EXT[7] #LVLB3 EXT7 - M11
set_location_assignment PIN_N11 -to EXT[8] #LVLB4 EXT8 - N11
set_location_assignment PIN_M12 -to EXT[9] #LVLB5 EXT9 - M12
atari_chips/pokeyv2/pokeymaxv4.5.qsf
set_location_assignment PIN_G13 -to EXT[8] # LOUT2.B2 LIN2.A2 G13 X
set_location_assignment PIN_G12 -to EXT[9] # LOUT2.B1 LIN2.A1 G12 X
set_location_assignment PIN_L13 -to EXT[10] # LOUT2.B8 LIN2.A8 L13 X
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to EXT[10]
set_location_assignment PIN_D9 -to AUD[3] # AUDR (CORRECTED)
set_location_assignment PIN_C9 -to AUD[4] # AUDL (CORRECTED)
set_location_assignment PIN_D9 -to AUD[3] # AUDL
set_location_assignment PIN_C9 -to AUD[4] # AUDR
set_location_assignment PIN_C10 -to AUD[1] # AUDINT
set_location_assignment PIN_M12 -to ADC_RX_p # LIN2.A10
atari_chips/pokeyv2/pokeymaxv4.qsf
set_location_assignment PIN_A12 -to BCLK #LVLA19,
set_location_assignment PIN_B12 -to KR1 #LVLA20,
set_location_assignment PIN_B13 -to EXT[10] #LVLA21,
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to EXT[10]
set_location_assignment PIN_C12 -to SID #LVLA22,
set_location_assignment PIN_D13 -to K[0] #LVLA23,
set_location_assignment PIN_C9 -to AUD[4]
set_location_assignment PIN_D9 -to AUD[3]
set_location_assignment PIN_C9 -to AUD[4] #R
set_location_assignment PIN_D9 -to AUD[3] #L
set_location_assignment PIN_C10 -to AUD[1]
set_location_assignment PIN_M12 -to ADC_RX_P #LVLB9
atari_chips/pokeyv2/sidmaxv1.qsf
set_global_assignment -name VHDL_FILE latch_delay_line.vhdl
set_global_assignment -name VHDL_FILE sigmadelta_1storder.vhd
set_global_assignment -name VHDL_FILE sigmadelta_2ndorder.vhd
set_global_assignment -name VHDL_FILE sigmadelta_2ndorder_dither.vhd
set_global_assignment -name VHDL_FILE filtered_sigmadelta.vhd
set_global_assignment -name VHDL_FILE generic_ram_infer.vhdl
set_global_assignment -name VHDL_FILE simple_low_pass_filter.vhdl
atari_chips/pokeyv2/sidmaxv1.vhd
signal MHZ358_ENABLE : std_logic;
-- spdif
signal spdif_mux : std_logic_vector(15 downto 0);
signal spdif_right : std_logic;
signal spdif_out : std_logic;
signal CLK6144 : std_logic; --spdif
signal AUDIO_2_FILTERED : unsigned(15 downto 0);
......
dac_0 : entity work.filtered_sigmadelta --pin37
GENERIC MAP
(
IMPLEMENTATION => 2,
LOWPASS => lowpass
IMPLEMENTATION => 4,
LOWPASS => lowpass,
LFSR_SEED => x"ACE2"
)
port map
(
......
dac_2 : entity work.filtered_sigmadelta
GENERIC MAP
(
IMPLEMENTATION => 2,
LOWPASS => lowpass
IMPLEMENTATION => 4,
LOWPASS => lowpass,
LFSR_SEED => x"BEEF"
)
port map
(
......
dac_3 : entity work.filtered_sigmadelta
GENERIC MAP
(
IMPLEMENTATION => 2,
LOWPASS => lowpass
IMPLEMENTATION => 4,
LOWPASS => lowpass,
LFSR_SEED => x"5A3C"
)
port map
(
......
-- Digital audio output
spdif_on : if enable_spdif=1 generate
-- todo: clock domain crossing!
spdif_mux <= std_logic_vector(audio_2_filtered) when spdif_right='0'
else std_logic_vector(audio_3_filtered);
filter_left : entity work.simple_low_pass_filter
PORT MAP
(
......
AUDIO_OUT => audio_3_filtered
);
-- todo: clock domain crossing!
spdif : entity work.spdif_transmitter
port map(
bit_clock => CLK6144, -- 128x Fsample (6.144MHz for 48K samplerate)
data_in(23 downto 8) => spdif_mux,
data_in(7 downto 0) => (others=>'0'),
address_out => spdif_right,
left_in(23) => not(audio_2_filtered(15)),
left_in(22 downto 8) => std_logic_vector(audio_2_filtered(14 downto 0)),
left_in(7 downto 0) => (others=>'0'),
right_in(23) => not(audio_3_filtered(15)),
right_in(22 downto 8) => std_logic_vector(audio_3_filtered(14 downto 0)),
right_in(7 downto 0) => (others=>'0'),
spdif_out => spdif_out
);
atari_chips/pokeyv2/spdif_transmitter.vhdl
entity spdif_transmitter is
port(
bit_clock : in std_logic; -- 128x Fsample (6.144MHz for 48K samplerate)
data_in : in std_logic_vector(23 downto 0);
address_out : out std_logic := '0'; -- 1 address bit means stereo only
left_in : in std_logic_vector(23 downto 0);
right_in : in std_logic_vector(23 downto 0);
spdif_out : out std_logic
);
end entity spdif_transmitter;
......
if bit_clock'event and bit_clock = '1' then
parity <= data_in_buffer(23) xor data_in_buffer(22) xor data_in_buffer(21) xor data_in_buffer(20) xor data_in_buffer(19) xor data_in_buffer(18) xor data_in_buffer(17) xor data_in_buffer(16) xor data_in_buffer(15) xor data_in_buffer(14) xor data_in_buffer(13) xor data_in_buffer(12) xor data_in_buffer(11) xor data_in_buffer(10) xor data_in_buffer(9) xor data_in_buffer(8) xor data_in_buffer(7) xor data_in_buffer(6) xor data_in_buffer(5) xor data_in_buffer(4) xor data_in_buffer(3) xor data_in_buffer(2) xor data_in_buffer(1) xor data_in_buffer(0) xor channel_status_shift(23);
if bit_counter = "000011" then
data_in_buffer <= data_in;
if frame_counter(0) = '0' then
data_in_buffer <= left_in;
else
data_in_buffer <= right_in;
end if;
end if;
if bit_counter = "111111" then
if frame_counter = "101111111" then
......
if bit_clock'event and bit_clock = '1' then
if bit_counter = "111111" then
if frame_counter = "101111111" then -- next frame is 0, load preamble Z
address_out <= '0';
channel_status_shift <= channel_status;
data_out_buffer <= "10011100";
else
if frame_counter(0) = '1' then -- next frame is even, load preamble X
channel_status_shift <= channel_status_shift(22 downto 0) & '0';
data_out_buffer <= "10010011";
address_out <= '0';
else -- next frame is odd, load preable Y
data_out_buffer <= "10010110";
address_out <= '1';
end if;
end if;
else

Also available in: Unified diff