Revision 1499
Added by markw 3 days ago
| 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
|
||
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).