Project

General

Profile

« Previous | Next » 

Revision 1454

Added by markw 8 months ago

Increase ADC volume. Try to decrease ADC noise by digital methods: FIR filter of problematic frequencies, silence ADC when nothing playing. Disable ADC for models that do not fit these features (M02/M08 with sample memory)

View differences:

atari_chips/pokeyv2/build.sh
"paddle_lvds"=>1,
"paddle_comp"=>0,
"enable_iox"=>0,
"enable_adc"=>1,
"enable_adc"=>0,
"pll_v2" => 0,
"optimisearea" => 1,
},
......
"paddle_lvds"=>1,
"paddle_comp"=>0,
"enable_iox"=>0,
"enable_adc"=>1,
"enable_adc"=>0,
"pll_v2" => 0,
"optimisearea" => 1,
},
......
`cp -r pokey $dir`;
`cp -r sample $dir`;
`cp -r covox $dir`;
`cp -r sigma_delta $dir`;
`cp -r *.bin $dir`;
`cp -r fir_*vhdl $dir`;
`cp -r fir_sample_buffer* $dir`;
`cp -r fir_buffer* $dir`;
chdir $dir;
atari_chips/pokeyv2/fir2_notch.m
pkg load signal;
fsample = 48000;
%fsample = 24000;
%notches = [15600/4,15600/2,15600];
cutoff = [15600,15600];
cutoff_norm = cutoff/(fsample/2);
%notches = load('notches');
%notches = notches.freqs;
notches = []
linepal = 312*49.86;
linentsc = 262*59.92;
for i=1:8
notches(end+1) = i*linepal/8;
notches(end+1) = i*linentsc/8;
end
notches(end+1) = linepal/64;
notches(end+1) = linentsc/64;
notches = notches(notches<cutoff(2));
notches_norm = notches/(fsample/2);
steps = 10000;
l=0;
%thr = 0.0008;
thr = 0.0016;
%thr = 0.0032;
for i = 0.0:1.0/steps:1.0
l=l+1;
pos(l) = i;
val = min(((i-notches_norm).^2).^0.5);
if val>thr
func(l)= 1.0;
else
func(l) = 0.0;
endif
if i>cutoff_norm(2)
func(l) = 0;
continue;
endif
if i>cutoff_norm(1)
cutoff_normd = cutoff_norm(2)-cutoff_norm(1);
func(l) = (cutoff_norm(2)-i)/cutoff_normd;
endif
end
fil_len = 2031;
fil = fir2(fil_len,pos,func);
bits = 16;
range = (2^bits-2)/2;
fil = round(fil*range)/range;
[h,w] = freqz(fil,1,10000);
f = pos;
m = func;
figure();
subplot(121);
plot(f,m,';target response;',w/pi,abs(h),';filter response;');
subplot(122);
plot(f,20*log10(m+1e-5),';target response (dB);',...
w/pi,20*log10(abs(h)),';filter response (dB);');
atari_chips/pokeyv2/fir_buffer.cmp
--Copyright (C) 2024 Intel Corporation. All rights reserved.
--Your use of Intel Corporation's design tools, logic functions
--and other software and tools, and any partner logic
--functions, and any output files from any of the foregoing
--(including device programming or simulation files), and any
--associated documentation or information are expressly subject
--to the terms and conditions of the Intel Program License
--Subscription Agreement, the Intel Quartus Prime License Agreement,
--the Intel FPGA IP License Agreement, or other applicable license
--agreement, including, without limitation, that your use is for
--the sole purpose of programming logic devices manufactured by
--Intel and sold by Intel or its authorized distributors. Please
--refer to the applicable agreement for further details, at
--https://fpgasoftware.intel.com/eula.
component fir_buffer
PORT
(
data : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
rdaddress : IN STD_LOGIC_VECTOR (9 DOWNTO 0);
rdclock : IN STD_LOGIC ;
wraddress : IN STD_LOGIC_VECTOR (9 DOWNTO 0);
wrclock : IN STD_LOGIC := '1';
wren : IN STD_LOGIC := '0';
q : OUT STD_LOGIC_VECTOR (31 DOWNTO 0)
);
end component;
atari_chips/pokeyv2/fir_buffer.qip
set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT"
set_global_assignment -name IP_TOOL_VERSION "23.1"
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{MAX 10}"
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "fir_buffer.vhd"]
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "fir_buffer.cmp"]
atari_chips/pokeyv2/fir_buffer.vhd
-- megafunction wizard: %RAM: 2-PORT%
-- GENERATION: STANDARD
-- VERSION: WM1.0
-- MODULE: altsyncram
-- ============================================================
-- File Name: fir_buffer.vhd
-- Megafunction Name(s):
-- altsyncram
--
-- Simulation Library Files(s):
-- altera_mf
-- ============================================================
-- ************************************************************
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
--
-- 23.1std.1 Build 993 05/14/2024 SC Lite Edition
-- ************************************************************
--Copyright (C) 2024 Intel Corporation. All rights reserved.
--Your use of Intel Corporation's design tools, logic functions
--and other software and tools, and any partner logic
--functions, and any output files from any of the foregoing
--(including device programming or simulation files), and any
--associated documentation or information are expressly subject
--to the terms and conditions of the Intel Program License
--Subscription Agreement, the Intel Quartus Prime License Agreement,
--the Intel FPGA IP License Agreement, or other applicable license
--agreement, including, without limitation, that your use is for
--the sole purpose of programming logic devices manufactured by
--Intel and sold by Intel or its authorized distributors. Please
--refer to the applicable agreement for further details, at
--https://fpgasoftware.intel.com/eula.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY altera_mf;
USE altera_mf.altera_mf_components.all;
ENTITY fir_buffer IS
PORT
(
data : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
rdaddress : IN STD_LOGIC_VECTOR (9 DOWNTO 0);
rdclock : IN STD_LOGIC ;
wraddress : IN STD_LOGIC_VECTOR (9 DOWNTO 0);
wrclock : IN STD_LOGIC := '1';
wren : IN STD_LOGIC := '0';
q : OUT STD_LOGIC_VECTOR (31 DOWNTO 0)
);
END fir_buffer;
ARCHITECTURE SYN OF fir_buffer IS
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (31 DOWNTO 0);
BEGIN
q <= sub_wire0(31 DOWNTO 0);
altsyncram_component : altsyncram
GENERIC MAP (
address_aclr_b => "NONE",
address_reg_b => "CLOCK1",
clock_enable_input_a => "BYPASS",
clock_enable_input_b => "BYPASS",
clock_enable_output_b => "BYPASS",
intended_device_family => "MAX 10",
lpm_type => "altsyncram",
numwords_a => 1021,
numwords_b => 1021,
operation_mode => "DUAL_PORT",
outdata_aclr_b => "NONE",
outdata_reg_b => "CLOCK1",
power_up_uninitialized => "FALSE",
widthad_a => 10,
widthad_b => 10,
width_a => 32,
width_b => 32,
width_byteena_a => 1
)
PORT MAP (
address_a => wraddress,
address_b => rdaddress,
clock0 => wrclock,
clock1 => rdclock,
data_a => data,
wren_a => wren,
q_b => sub_wire0
);
END SYN;
-- ============================================================
-- CNX file retrieval info
-- ============================================================
-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
-- Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0"
-- Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
-- Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
-- Retrieval info: PRIVATE: CLRdata NUMERIC "0"
-- Retrieval info: PRIVATE: CLRq NUMERIC "0"
-- Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
-- Retrieval info: PRIVATE: CLRrren NUMERIC "0"
-- Retrieval info: PRIVATE: CLRwraddress NUMERIC "0"
-- Retrieval info: PRIVATE: CLRwren NUMERIC "0"
-- Retrieval info: PRIVATE: Clock NUMERIC "1"
-- Retrieval info: PRIVATE: Clock_A NUMERIC "0"
-- Retrieval info: PRIVATE: Clock_B NUMERIC "0"
-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
-- Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0"
-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B"
-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "MAX 10"
-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
-- Retrieval info: PRIVATE: MEMSIZE NUMERIC "32672"
-- Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0"
-- Retrieval info: PRIVATE: MIFfilename STRING ""
-- Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2"
-- Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "1"
-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3"
-- Retrieval info: PRIVATE: REGdata NUMERIC "1"
-- Retrieval info: PRIVATE: REGq NUMERIC "0"
-- Retrieval info: PRIVATE: REGrdaddress NUMERIC "1"
-- Retrieval info: PRIVATE: REGrren NUMERIC "1"
-- Retrieval info: PRIVATE: REGwraddress NUMERIC "1"
-- Retrieval info: PRIVATE: REGwren NUMERIC "1"
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
-- Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0"
-- Retrieval info: PRIVATE: UseDPRAM NUMERIC "1"
-- Retrieval info: PRIVATE: VarWidth NUMERIC "0"
-- Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "32"
-- Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "32"
-- Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "32"
-- Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "32"
-- Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0"
-- Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: enable NUMERIC "0"
-- Retrieval info: PRIVATE: rden NUMERIC "0"
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
-- Retrieval info: CONSTANT: ADDRESS_ACLR_B STRING "NONE"
-- Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK1"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "MAX 10"
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "1021"
-- Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "1021"
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT"
-- Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
-- Retrieval info: CONSTANT: OUTDATA_REG_B STRING "CLOCK1"
-- Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "10"
-- Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "10"
-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "32"
-- Retrieval info: CONSTANT: WIDTH_B NUMERIC "32"
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
-- Retrieval info: USED_PORT: data 0 0 32 0 INPUT NODEFVAL "data[31..0]"
-- Retrieval info: USED_PORT: q 0 0 32 0 OUTPUT NODEFVAL "q[31..0]"
-- Retrieval info: USED_PORT: rdaddress 0 0 10 0 INPUT NODEFVAL "rdaddress[9..0]"
-- Retrieval info: USED_PORT: rdclock 0 0 0 0 INPUT NODEFVAL "rdclock"
-- Retrieval info: USED_PORT: wraddress 0 0 10 0 INPUT NODEFVAL "wraddress[9..0]"
-- Retrieval info: USED_PORT: wrclock 0 0 0 0 INPUT VCC "wrclock"
-- Retrieval info: USED_PORT: wren 0 0 0 0 INPUT GND "wren"
-- Retrieval info: CONNECT: @address_a 0 0 10 0 wraddress 0 0 10 0
-- Retrieval info: CONNECT: @address_b 0 0 10 0 rdaddress 0 0 10 0
-- Retrieval info: CONNECT: @clock0 0 0 0 0 wrclock 0 0 0 0
-- Retrieval info: CONNECT: @clock1 0 0 0 0 rdclock 0 0 0 0
-- Retrieval info: CONNECT: @data_a 0 0 32 0 data 0 0 32 0
-- Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
-- Retrieval info: CONNECT: q 0 0 32 0 @q_b 0 0 32 0
-- Retrieval info: GEN_FILE: TYPE_NORMAL fir_buffer.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL fir_buffer.inc FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL fir_buffer.cmp TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL fir_buffer.bsf FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL fir_buffer_inst.vhd FALSE
-- Retrieval info: LIB_FILE: altera_mf
atari_chips/pokeyv2/fir_filter.vhdl
---------------------------------------------------------------------------
-- (c) 2024 mark watson
-- I am happy for anyone to use this for non-commercial use.
-- If my vhdl files are used commercially or otherwise sold,
-- please contact me for explicit permission at scrameta (gmail).
-- This applies for source and binary form and derived works.
---------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
use IEEE.STD_LOGIC_MISC.all;
ENTITY fir_filter IS
GENERIC
(
sample_bits : integer := 16;
filter_bits : integer := 16;
filter_len : integer := 2048
);
PORT
(
FILTER_CLK : IN STD_LOGIC;
RESET_N : IN STD_LOGIC;
SAMPLE_ENABLE : IN STD_LOGIC;
SAMPLE_DATA : IN SIGNED(sample_bits-1 downto 0);
SAMPLE_OUT : OUT SIGNED(sample_bits-1 downto 0);
FLASH_CLK : IN STD_LOGIC;
FLASH_REQUEST : OUT STD_LOGIC;
FLASH_ADDRESS : OUT STD_LOGIC_VECTOR(9 downto 0);
FLASH_DATA : IN STD_LOGIC_VECTOR(31 downto 0);
FLASH_READY : IN STD_LOGIC
);
END fir_filter;
ARCHITECTURE vhdl OF fir_filter IS
function log2c(n : integer) return integer is
variable m,p : integer;
begin
m := 0;
p := 1;
while p<n loop
m:=m+1;
p:=p*2;
end loop;
return m;
end log2c;
constant ADDR_WIDTH : natural := log2c(FILTER_LEN);
signal sample_ram_write_enable : std_logic;
signal sample_ram_address1 : std_logic_vector(ADDR_WIDTH-1 downto 0);
signal sample_ram_address2 : std_logic_vector(ADDR_WIDTH-1 downto 0);
signal sample_ram_data1_reg : std_logic_vector(SAMPLE_BITS-1 downto 0);
signal sample_ram_data1_next : std_logic_vector(SAMPLE_BITS-1 downto 0);
signal sample_ram_data2_reg : std_logic_vector(SAMPLE_BITS-1 downto 0);
signal sample_ram_data2_next : std_logic_vector(SAMPLE_BITS-1 downto 0);
signal sample_ram_write_address_reg : std_logic_vector(ADDR_WIDTH-1 downto 0);
signal sample_ram_write_address_next : std_logic_vector(ADDR_WIDTH-1 downto 0);
signal sample_ram_read_address1_reg : std_logic_vector(ADDR_WIDTH-1 downto 0);
signal sample_ram_read_address1_next : std_logic_vector(ADDR_WIDTH-1 downto 0);
signal sample_ram_read_address2_reg : std_logic_vector(ADDR_WIDTH-1 downto 0);
signal sample_ram_read_address2_next : std_logic_vector(ADDR_WIDTH-1 downto 0);
signal fir_rom_address_reg : std_logic_vector(ADDR_WIDTH-2 downto 0);
signal fir_rom_address_next : std_logic_vector(ADDR_WIDTH-2 downto 0);
signal fir_rom_data1_reg : std_logic_vector(FILTER_BITS-1 downto 0);
signal fir_rom_data1_next : std_logic_vector(FILTER_BITS-1 downto 0);
signal fir_rom_data2_reg : std_logic_vector(FILTER_BITS-1 downto 0);
signal fir_rom_data2_next : std_logic_vector(FILTER_BITS-1 downto 0);
signal mult1_reg : signed(SAMPLE_BITS+FILTER_BITS-1 downto 0);
signal mult1_next : signed(SAMPLE_BITS+FILTER_BITS-1 downto 0); -- up to 18x18
signal mult2_reg : signed(SAMPLE_BITS+FILTER_BITS-1 downto 0);
signal mult2_next : signed(SAMPLE_BITS+FILTER_BITS-1 downto 0); -- up to 18x18
signal accumulator_reg : signed(SAMPLE_BITS+FILTER_BITS-1 downto 0);
signal accumulator_next : signed(SAMPLE_BITS+FILTER_BITS-1 downto 0); -- up to 18x18
signal sample_out_reg : signed(SAMPLE_BITS-1 downto 0);
signal sample_out_next : signed(SAMPLE_BITS-1 downto 0);
signal state_reg : std_logic_vector(2 downto 0);
signal state_next : std_logic_vector(2 downto 0);
constant state_wait_sample : std_logic_vector(2 downto 0) := "001";
constant state_fir_prepare : std_logic_vector(2 downto 0) := "010";
constant state_fir_compute1 : std_logic_vector(2 downto 0) := "011";
constant state_fir_compute2 : std_logic_vector(2 downto 0) := "100";
constant state_fir_compute3 : std_logic_vector(2 downto 0) := "101";
constant state_fir_compute4 : std_logic_vector(2 downto 0) := "110";
constant state_fir_compute5 : std_logic_vector(2 downto 0) := "111";
-- Clock domain flash
signal fir_rom_write_enable : std_logic;
signal fir_rom_write_address_reg : std_logic_vector(ADDR_WIDTH-2 downto 0);
signal fir_rom_write_address_next : std_logic_vector(ADDR_WIDTH-2 downto 0);
signal flash_state_reg : std_logic_vector(1 downto 0);
signal flash_state_next : std_logic_vector(1 downto 0);
constant flash_state_init : std_logic_vector(1 downto 0) := "00";
constant flash_state_request : std_logic_vector(1 downto 0) := "01";
constant flash_state_wait : std_logic_vector(1 downto 0) := "10";
constant flash_state_done : std_logic_vector(1 downto 0) := "11";
-- pipeline
-- rom->register
-- register->multiplier
-- multiplier->adder
BEGIN
process(filter_clk,reset_n)
begin
if (reset_n='0') then
sample_ram_write_address_reg <= (others=>'0');
sample_ram_read_address1_reg <= (others=>'0');
sample_ram_read_address2_reg <= (others=>'0');
fir_rom_address_reg <= (others=>'0');
mult1_reg <= (others=>'0');
mult2_reg <= (others=>'0');
accumulator_reg <= (others=>'0');
sample_out_reg <= (others=>'0');
state_reg <= state_wait_sample;
sample_ram_data1_reg <= (others=>'0');
sample_ram_data2_reg <= (others=>'0');
fir_rom_data1_reg <= (others=>'0');
fir_rom_data2_reg <= (others=>'0');
elsif (filter_clk'event and filter_clk='1') then
sample_ram_write_address_reg <= sample_ram_write_address_next;
sample_ram_read_address1_reg <= sample_ram_read_address1_next;
sample_ram_read_address2_reg <= sample_ram_read_address2_next;
fir_rom_address_reg <= fir_rom_address_next;
mult1_reg <= mult1_next;
mult2_reg <= mult2_next;
accumulator_reg <= accumulator_next;
sample_out_reg <= sample_out_next;
state_reg <= state_next;
sample_ram_data1_reg <= sample_ram_data1_next;
sample_ram_data2_reg <= sample_ram_data2_next;
fir_rom_data1_reg <= fir_rom_data1_next;
fir_rom_data2_reg <= fir_rom_data2_next;
end if;
end process;
process(flash_clk,reset_n)
begin
if (reset_n='0') then
flash_state_reg <= flash_state_init;
fir_rom_write_address_reg <= (others=>'0');
elsif (flash_clk'event and flash_clk='1') then
flash_state_reg <= flash_state_next;
fir_rom_write_address_reg <= fir_rom_write_address_next;
end if;
end process;
sample_buffer_inst : entity work.fir_sample_buffer
PORT MAP
(
address_a => sample_ram_address1,
address_b => sample_ram_address2,
clock => filter_clk,
data_a => std_logic_vector(sample_data),
data_b => (others=>'0'),
wren_a => sample_ram_write_enable,
wren_b => '0',
q_a => sample_ram_data1_next,
q_b => sample_ram_data2_next
);
fir_data_inst : entity work.fir_buffer
PORT MAP
(
rdclock => filter_clk,
rdaddress => fir_rom_address_reg,
q((filter_bits*2)-1 downto filter_bits) => fir_rom_data1_next,
q(filter_bits-1 downto 0) => fir_rom_data2_next,
wrclock => flash_clk,
wraddress => fir_rom_write_address_reg,
data => flash_data,
wren => fir_rom_write_enable
);
-- res = sum(Fi*Si)
-- so...
-- sample in -> store sample
-- iterate over filter and samples doing multiply and add
-- store result in register
process(state_reg,
sample_enable,
sample_ram_data1_reg,sample_ram_data2_reg,fir_rom_data1_reg,fir_rom_data2_reg,mult1_reg,mult2_reg,accumulator_reg,
sample_ram_write_address_reg,sample_ram_read_address1_reg, sample_ram_read_address2_reg,
fir_rom_address_reg,
sample_out_reg
) is
begin
state_next <= state_reg;
sample_ram_write_address_next <= sample_ram_write_address_reg;
sample_ram_read_address1_next <= std_logic_vector(unsigned(sample_ram_read_address1_reg)-2);
sample_ram_read_address2_next <= std_logic_vector(unsigned(sample_ram_read_address2_reg)-2);
fir_rom_address_next <= std_logic_vector(unsigned(fir_rom_address_reg)+1);
sample_out_next <= sample_out_reg;
mult1_next <= signed(sample_ram_data1_reg) * signed(fir_rom_data1_reg);
mult2_next <= signed(sample_ram_data2_reg) * signed(fir_rom_data2_reg);
accumulator_next <= accumulator_reg + mult1_reg + mult2_reg;
sample_ram_write_enable <= '0';
sample_ram_address1 <= sample_ram_read_address1_reg;
sample_ram_address2 <= sample_ram_read_address2_reg;
if (sample_enable='1') then
sample_ram_write_address_next <= std_logic_vector(unsigned(sample_ram_write_address_reg)-1);
end if;
case state_reg is
when state_wait_sample =>
sample_ram_write_enable <= sample_enable;
sample_ram_address1 <= sample_ram_write_address_reg;
if (sample_enable='1') then
state_next <= state_fir_prepare;
--sample_ram_read_address1_next <= std_logic_vector(unsigned(sample_ram_write_address_reg) + to_unsigned(filter_len-1,ADDR_WIDTH));
--sample_ram_read_address2_next <= std_logic_vector(unsigned(sample_ram_write_address_reg) + to_unsigned(filter_len-2,ADDR_WIDTH));
sample_ram_read_address1_next <= std_logic_vector(unsigned(sample_ram_write_address_reg) + to_unsigned(0,ADDR_WIDTH));
sample_ram_read_address2_next <= std_logic_vector(unsigned(sample_ram_write_address_reg) + to_unsigned(-1,ADDR_WIDTH));
fir_rom_address_next <= (others=>'0');
end if;
when state_fir_prepare =>
state_next <= state_fir_compute1;
when state_fir_compute1 =>
state_next <= state_fir_compute2;
when state_fir_compute2 =>
state_next <= state_fir_compute3;
when state_fir_compute3 =>
state_next <= state_fir_compute4;
accumulator_next <= (others=>'0');
when state_fir_compute4 => --6
-- pipeline is ready, we have data to add to the accumulator
state_next <= state_fir_compute5;
when state_fir_compute5 =>
-- When entering this state we have the accum res
-- If we have fir length of 1, then it will be 0 in compute1,-1 in compute2 and -2 in compute3. So done==-2 (ffff...ffe)
if (fir_rom_address_reg = std_logic_vector(to_unsigned((filter_len/2)-1,ADDR_WIDTH-1) + 5)) then
state_next <= state_wait_sample;
sample_out_next <= accumulator_reg(FILTER_BITS+SAMPLE_BITS-2 downto FILTER_BITS-1);
end if;
when others=>
state_next <=state_wait_sample;
end case;
end process;
-- write domain
process(flash_state_reg,
fir_rom_write_address_reg,
flash_ready
) is
begin
flash_state_next <= flash_state_reg;
fir_rom_write_address_next <= fir_rom_write_address_reg;
fir_rom_write_enable <= '0';
flash_request <= '0';
case flash_state_reg is
when flash_state_init =>
fir_rom_write_address_next <= std_logic_vector(to_unsigned(filter_len/2-1,ADDR_WIDTH-1));
flash_state_next <= flash_state_request;
when flash_state_request =>
flash_request <= '1';
flash_state_next <= flash_state_wait;
when flash_state_wait =>
flash_request <= '1';
if (flash_ready = '1') then
fir_rom_write_enable <= '1';
fir_rom_write_address_next <= std_logic_vector(unsigned(fir_rom_write_address_reg)-1);
flash_request <= '0';
if (or_reduce(fir_rom_write_address_reg)='0') then
flash_state_next <= flash_state_done;
else
flash_state_next <= flash_state_wait;
end if;
end if;
when flash_state_done =>
-- nothing
when others=>
flash_state_next <=flash_state_init;
end case;
end process;
-- outputs
sample_out <= sample_out_reg;
FLASH_ADDRESS <= fir_rom_write_address_reg;
end vhdl;
--ARCHITECTURE rtl OF sync_rom IS
--BEGIN
--PROCESS (clock)
-- BEGIN
-- IF rising_edge (clock) THEN
-- CASE address IS
-- WHEN "00000000" => data_out <= "101111";
-- WHEN "00000001" => data_out <= "110110";
-- ...
-- WHEN "11111110" => data_out <= "000001";
-- WHEN "11111111" => data_out <= "101010";
-- WHEN OTHERS => data_out <= "101111";
-- END CASE;
-- END IF;
-- END PROCESS;
--END rtl;
atari_chips/pokeyv2/fir_sample_buffer.cmp
--Copyright (C) 2024 Intel Corporation. All rights reserved.
--Your use of Intel Corporation's design tools, logic functions
--and other software and tools, and any partner logic
--functions, and any output files from any of the foregoing
--(including device programming or simulation files), and any
--associated documentation or information are expressly subject
--to the terms and conditions of the Intel Program License
--Subscription Agreement, the Intel Quartus Prime License Agreement,
--the Intel FPGA IP License Agreement, or other applicable license
--agreement, including, without limitation, that your use is for
--the sole purpose of programming logic devices manufactured by
--Intel and sold by Intel or its authorized distributors. Please
--refer to the applicable agreement for further details, at
--https://fpgasoftware.intel.com/eula.
component fir_sample_buffer
PORT
(
address_a : IN STD_LOGIC_VECTOR (10 DOWNTO 0);
address_b : IN STD_LOGIC_VECTOR (10 DOWNTO 0);
clock : IN STD_LOGIC := '1';
data_a : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
data_b : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
wren_a : IN STD_LOGIC := '0';
wren_b : IN STD_LOGIC := '0';
q_a : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
q_b : OUT STD_LOGIC_VECTOR (15 DOWNTO 0)
);
end component;
atari_chips/pokeyv2/fir_sample_buffer.qip
set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT"
set_global_assignment -name IP_TOOL_VERSION "23.1"
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{MAX 10}"
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "fir_sample_buffer.vhd"]
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "fir_sample_buffer.cmp"]
atari_chips/pokeyv2/fir_sample_buffer.vhd
-- megafunction wizard: %RAM: 2-PORT%
-- GENERATION: STANDARD
-- VERSION: WM1.0
-- MODULE: altsyncram
-- ============================================================
-- File Name: fir_sample_buffer.vhd
-- Megafunction Name(s):
-- altsyncram
--
-- Simulation Library Files(s):
-- altera_mf
-- ============================================================
-- ************************************************************
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
--
-- 23.1std.1 Build 993 05/14/2024 SC Lite Edition
-- ************************************************************
--Copyright (C) 2024 Intel Corporation. All rights reserved.
--Your use of Intel Corporation's design tools, logic functions
--and other software and tools, and any partner logic
--functions, and any output files from any of the foregoing
--(including device programming or simulation files), and any
--associated documentation or information are expressly subject
--to the terms and conditions of the Intel Program License
--Subscription Agreement, the Intel Quartus Prime License Agreement,
--the Intel FPGA IP License Agreement, or other applicable license
--agreement, including, without limitation, that your use is for
--the sole purpose of programming logic devices manufactured by
--Intel and sold by Intel or its authorized distributors. Please
--refer to the applicable agreement for further details, at
--https://fpgasoftware.intel.com/eula.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY altera_mf;
USE altera_mf.altera_mf_components.all;
ENTITY fir_sample_buffer IS
PORT
(
address_a : IN STD_LOGIC_VECTOR (10 DOWNTO 0);
address_b : IN STD_LOGIC_VECTOR (10 DOWNTO 0);
clock : IN STD_LOGIC := '1';
data_a : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
data_b : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
wren_a : IN STD_LOGIC := '0';
wren_b : IN STD_LOGIC := '0';
q_a : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
q_b : OUT STD_LOGIC_VECTOR (15 DOWNTO 0)
);
END fir_sample_buffer;
ARCHITECTURE SYN OF fir_sample_buffer IS
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (15 DOWNTO 0);
SIGNAL sub_wire1 : STD_LOGIC_VECTOR (15 DOWNTO 0);
BEGIN
q_a <= sub_wire0(15 DOWNTO 0);
q_b <= sub_wire1(15 DOWNTO 0);
altsyncram_component : altsyncram
GENERIC MAP (
address_reg_b => "CLOCK0",
clock_enable_input_a => "BYPASS",
clock_enable_input_b => "BYPASS",
clock_enable_output_a => "BYPASS",
clock_enable_output_b => "BYPASS",
indata_reg_b => "CLOCK0",
intended_device_family => "MAX 10",
lpm_type => "altsyncram",
numwords_a => 2048,
numwords_b => 2048,
operation_mode => "BIDIR_DUAL_PORT",
outdata_aclr_a => "NONE",
outdata_aclr_b => "NONE",
outdata_reg_a => "CLOCK0",
outdata_reg_b => "CLOCK0",
power_up_uninitialized => "FALSE",
read_during_write_mode_mixed_ports => "DONT_CARE",
read_during_write_mode_port_a => "NEW_DATA_WITH_NBE_READ",
read_during_write_mode_port_b => "NEW_DATA_WITH_NBE_READ",
widthad_a => 11,
widthad_b => 11,
width_a => 16,
width_b => 16,
width_byteena_a => 1,
width_byteena_b => 1,
wrcontrol_wraddress_reg_b => "CLOCK0"
)
PORT MAP (
address_a => address_a,
address_b => address_b,
clock0 => clock,
data_a => data_a,
data_b => data_b,
wren_a => wren_a,
wren_b => wren_b,
q_a => sub_wire0,
q_b => sub_wire1
);
END SYN;
-- ============================================================
-- CNX file retrieval info
-- ============================================================
-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
-- Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0"
-- Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
-- Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
-- Retrieval info: PRIVATE: CLRdata NUMERIC "0"
-- Retrieval info: PRIVATE: CLRq NUMERIC "0"
-- Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
-- Retrieval info: PRIVATE: CLRrren NUMERIC "0"
-- Retrieval info: PRIVATE: CLRwraddress NUMERIC "0"
-- Retrieval info: PRIVATE: CLRwren NUMERIC "0"
-- Retrieval info: PRIVATE: Clock NUMERIC "0"
-- Retrieval info: PRIVATE: Clock_A NUMERIC "0"
-- Retrieval info: PRIVATE: Clock_B NUMERIC "0"
-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
-- Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "1"
-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "MAX 10"
-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
-- Retrieval info: PRIVATE: MEMSIZE NUMERIC "32768"
-- Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "1"
-- Retrieval info: PRIVATE: MIFfilename STRING ""
-- Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "3"
-- Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "1"
-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "4"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "4"
-- Retrieval info: PRIVATE: REGdata NUMERIC "1"
-- Retrieval info: PRIVATE: REGq NUMERIC "1"
-- Retrieval info: PRIVATE: REGrdaddress NUMERIC "0"
-- Retrieval info: PRIVATE: REGrren NUMERIC "0"
-- Retrieval info: PRIVATE: REGwraddress NUMERIC "1"
-- Retrieval info: PRIVATE: REGwren NUMERIC "1"
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
-- Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0"
-- Retrieval info: PRIVATE: UseDPRAM NUMERIC "1"
-- Retrieval info: PRIVATE: VarWidth NUMERIC "0"
-- Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "16"
-- Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "16"
-- Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "16"
-- Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "16"
-- Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "1"
-- Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: enable NUMERIC "0"
-- Retrieval info: PRIVATE: rden NUMERIC "0"
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
-- Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
-- Retrieval info: CONSTANT: INDATA_REG_B STRING "CLOCK0"
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "MAX 10"
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "2048"
-- Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "2048"
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "BIDIR_DUAL_PORT"
-- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
-- Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
-- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0"
-- Retrieval info: CONSTANT: OUTDATA_REG_B STRING "CLOCK0"
-- Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
-- Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE"
-- Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_A STRING "NEW_DATA_WITH_NBE_READ"
-- Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_B STRING "NEW_DATA_WITH_NBE_READ"
-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "11"
-- Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "11"
-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "16"
-- Retrieval info: CONSTANT: WIDTH_B NUMERIC "16"
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_B NUMERIC "1"
-- Retrieval info: CONSTANT: WRCONTROL_WRADDRESS_REG_B STRING "CLOCK0"
-- Retrieval info: USED_PORT: address_a 0 0 11 0 INPUT NODEFVAL "address_a[10..0]"
-- Retrieval info: USED_PORT: address_b 0 0 11 0 INPUT NODEFVAL "address_b[10..0]"
-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
-- Retrieval info: USED_PORT: data_a 0 0 16 0 INPUT NODEFVAL "data_a[15..0]"
-- Retrieval info: USED_PORT: data_b 0 0 16 0 INPUT NODEFVAL "data_b[15..0]"
-- Retrieval info: USED_PORT: q_a 0 0 16 0 OUTPUT NODEFVAL "q_a[15..0]"
-- Retrieval info: USED_PORT: q_b 0 0 16 0 OUTPUT NODEFVAL "q_b[15..0]"
-- Retrieval info: USED_PORT: wren_a 0 0 0 0 INPUT GND "wren_a"
-- Retrieval info: USED_PORT: wren_b 0 0 0 0 INPUT GND "wren_b"
-- Retrieval info: CONNECT: @address_a 0 0 11 0 address_a 0 0 11 0
-- Retrieval info: CONNECT: @address_b 0 0 11 0 address_b 0 0 11 0
-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
-- Retrieval info: CONNECT: @data_a 0 0 16 0 data_a 0 0 16 0
-- Retrieval info: CONNECT: @data_b 0 0 16 0 data_b 0 0 16 0
-- Retrieval info: CONNECT: @wren_a 0 0 0 0 wren_a 0 0 0 0
-- Retrieval info: CONNECT: @wren_b 0 0 0 0 wren_b 0 0 0 0
-- Retrieval info: CONNECT: q_a 0 0 16 0 @q_a 0 0 16 0
-- Retrieval info: CONNECT: q_b 0 0 16 0 @q_b 0 0 16 0
-- Retrieval info: GEN_FILE: TYPE_NORMAL fir_sample_buffer.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL fir_sample_buffer.inc FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL fir_sample_buffer.cmp TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL fir_sample_buffer.bsf FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL fir_sample_buffer_inst.vhd FALSE
-- Retrieval info: LIB_FILE: altera_mf
atari_chips/pokeyv2/init.c
}
fclose(f);
int fir_base = 0xc00*4;
unsigned short * fir = (unsigned short *)(buffer+fir_base);
FILE * fr =fopen("fir_rom.bin","rb");
fread(fir,2,2032,fr);
fclose(fr);
FILE * x =fopen("init_0.bin","w");
fwrite(&buffer[0],1,32768,x);
fclose(x);
atari_chips/pokeyv2/pokeymax.vhd
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(20 downto 0);
adc_valid : out std_logic
);
end component;
component int_osc is
port (
clkout : out std_logic; -- clkout.clk
......
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_in_signed : signed(15 downto 0);
signal adc_out_signed : signed(15 downto 0);
signal adc_min_reg : signed(11 downto 0);
signal adc_min_next : signed(11 downto 0);
signal adc_max_reg : signed(11 downto 0);
signal adc_max_next : signed(11 downto 0);
signal adc_diff_reg : unsigned(11 downto 0);
signal adc_diff_next : unsigned(11 downto 0);
signal adc_enabled_reg : unsigned(5 downto 0);
signal adc_enabled_next : unsigned(5 downto 0);
signal enable_reset_min_max_pre : std_logic;
signal enable_reset_min_max : std_logic;
signal adc_valid : std_logic;
signal adc_output : std_logic_vector(20 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
);
......
c1 => CLK116, --113ish
c2 => CLK106, --106ish
locked => RESET_N);
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);
CLK49152 <= CLK0;
end generate;
......
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,
......
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;
......
end generate ps2_off;
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_enabled_reg <= (others=>'0');
adc_use_reg <= (others=>'0');
adc_min_reg <= (others=>'1');
adc_max_reg <= (others=>'0');
adc_diff_reg <= (others=>'0');
elsif (CLK49152'event and CLK49152='1') then
adc_reg <= adc_next;
adc_enabled_reg <= adc_enabled_next;
adc_use_reg <= adc_use_next;
adc_min_reg <= adc_min_next;
adc_max_reg <= adc_max_next;
adc_diff_reg <= adc_diff_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);
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
);
SIO_AUDIO <= unsigned(not(adc_use_reg(15))&adc_use_reg(14 downto 0));
process(sum_reg,sample_reg,toggle_reg)
enable_div : work.enable_divider
generic map (COUNT=>128)
port map(clk=>CLK49152,reset_n=>reset_n,enable_in=>'1',enable_out=>enable_reset_min_max_pre);
enable_div2 : work.enable_divider
generic map (COUNT=>128)
port map(clk=>CLK49152,reset_n=>reset_n,enable_in=>enable_reset_min_max_pre,enable_out=>enable_reset_min_max);
process(adc_reg,adc_output,adc_valid)
variable adc_shrunk : signed(20 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(20)) & adc_output(19 downto 0));
adc_next <= adc_shrunk(18 downto (18-16+1)); --*2
end if;
end process;
sample_next <= sum_reg;
process(adc_out_signed,adc_min_reg,adc_max_reg,adc_diff_reg,enable_reset_min_max,adc_enabled_reg)
variable detected : std_logic;
begin
adc_min_next <= adc_min_reg;
adc_max_next <= adc_max_reg;
adc_diff_next <= unsigned(adc_max_reg-adc_min_reg);
adc_enabled_next <= adc_enabled_reg;
if (adc_out_signed(15 downto 4)<adc_min_reg) then
adc_min_next <= adc_out_signed(15 downto 4);
end if;
if (adc_out_signed(15 downto 4)>adc_max_reg) then
adc_max_next <= adc_out_signed(15 downto 4);
end if;
if (enable_reset_min_max='1') then
detected := '0';
if (adc_diff_reg>16) then
detected := '1';
end if;
if (detected='1' and adc_enabled_reg<63) then
adc_enabled_next <= adc_enabled_reg+1;
end if;
if (detected='0' and adc_enabled_reg>0) then
adc_enabled_next <= adc_enabled_reg-1;
end if;
adc_min_next(11) <= '0';
adc_min_next(10 downto 0) <= (others=>'1');
adc_max_next(11) <= '1';
adc_max_next(10 downto 0) <= (others=>'0');
end if;
end process;
process(adc_reg,adc_enabled_reg,adc_out_signed)
begin
adc_use_next <= adc_use_reg;
if (adc_enabled_reg>=32) then
adc_use_next <= adc_out_signed;
end if;
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');
SIO_AUDIO(15 downto 12) <= (others=>'0');
SIO_AUDIO(11) <= SIO_RXD_SYNC;
SIO_AUDIO(10 downto 0) <= (others=>'0');
end generate adc_off;
paddle_lvds_on : if paddle_lvds=1 generate
atari_chips/pokeyv2/pokeymaxv4.qsf
set_location_assignment PIN_L1 -to K[5] #LVLB22,
set_location_assignment PIN_K1 -to KR2 #LVLB23,
set_instance_assignment -name CURRENT_STRENGTH_NEW "2MA" -to K[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW "2MA" -to K[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW "2MA" -to K[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW "2MA" -to K[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW "2MA" -to K[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW "2MA" -to K[5]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to K[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to K[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to K[2]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to K[3]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to K[4]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to K[5]
#set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to K[0]
#set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to K[1]
#set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to K[2]
#set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to K[3]
#set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to K[4]
#set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to K[5]
set_location_assignment PIN_G9 -to CLK_SLOW #CLK2 - G9
set_location_assignment PIN_H8 -to CLK_OUT #OUT - H8
set_location_assignment PIN_E13 -to CLK0
......
set_global_assignment -name VHDL_FILE sigmadelta_1storder.vhd
set_global_assignment -name VHDL_FILE sigmadelta_2ndorder.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 generic_ram_infer.vhdl
set_global_assignment -name VHDL_FILE simple_low_pass_filter.vhdl
set_global_assignment -name VHDL_FILE pokey/pokey_poly_17_9.vhdl
......
set_global_assignment -name VHDL_FILE sample/adpcm.vhdl
set_global_assignment -name VHDL_FILE sample/top.vhdl
set_global_assignment -name VHDL_FILE covox/top.vhdl
set_global_assignment -name SYSTEMVERILOG_FILE sigma_delta/sigma_delta_adc.sv
set_global_assignment -name SYSTEMVERILOG_FILE sigma_delta/cic_comb.sv
set_global_assignment -name SYSTEMVERILOG_FILE sigma_delta/cic_integrator.sv
set_global_assignment -name SYSTEMVERILOG_FILE sigma_delta/fir_compensator.sv
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 pllv3.qip
set_global_assignment -name QIP_FILE flash/synthesis/flash.qip
set_global_assignment -name QIP_FILE lvds_tx.qip
set_global_assignment -name QIP_FILE lvds_rx.qip
set_global_assignment -name QIP_FILE paddle_gpio.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/sigma_delta/cic_comb.sv
// Dave Muscle
//Decimator designed for use in a multi-stage CIC filter
/*
x[n] --|---------> + ----> y[n]
| x (-1)
---[z^-1]-->|
*/
module cic_comb #(
parameter int WIDTH = 32
)(
input bit clk,
input bit rst,
input bit ena,
input bit [WIDTH-1:0] data_in ,
output bit [WIDTH-1:0] data_out
);
bit [WIDTH-1:0] r_data;
always_ff @(posedge clk) begin
if(ena) begin
r_data <= data_in ;
data_out <= r_data - data_in ;
end
if(rst) begin
data_out <= 0;
r_data <= 0;
end
end
endmodule: cic_comb
atari_chips/pokeyv2/sigma_delta/cic_integrator.sv
// Dave Muscle
//Integrator designed for use in a multi-stage CIC filter
/*
x[n] ---> + --> y[n] --->
| |
|<--[z^-1]----|
*/
module cic_integrator #(
parameter int WIDTH = 32
)(
input bit clk,
input bit rst,
input bit ena,
input bit [WIDTH-1:0] data_in ,
output bit [WIDTH-1:0] data_out
);
always_ff @(posedge clk) begin
if(ena) begin
data_out <= data_out + data_in ;
end
if(rst) begin
data_out <= 0;
end
end
endmodule: cic_integrator
atari_chips/pokeyv2/sigma_delta/fir_compensator.sv
// DaveMuscle
// Multiplier-less FIR compensator meant for post-processing CIC filters
// ALPHA is reduced to a fraction out of 8, eg: 0.358 -> 0.375 = 3/8
// Implicitly casts data to signed format, unsigned will not work
//https://dsp.stackexchange.com/questions/19584/how-to-make-cic-compensation-filter
/*
x[n] ------> [ z^-1 ] -----
| |
+ <-- [ z^-1 ] ----|
| x (1+a)
(-a/2) x |
| |
-------------------+---> y[n]
*/
module fir_compensator #(
parameter int WIDTH = 32,
parameter int ALPHA_8 = 2
)(
input bit clk,
input bit rst,
input bit ena,
input bit [WIDTH-1:0] data_in ,
output bit [WIDTH-1:0] data_out
);
bit signed [WIDTH-1:0] d1, d2;
bit signed [WIDTH-1:0] sum, dly;
bit signed [WIDTH-1:0] sum_mult;
bit signed [WIDTH-1:0] dly_mult;
bit signed [WIDTH-1:0] dly_dly;
// h = (-a / 2) * (n'' + n) + (1+a)*n'
// multiply by 'a/2' on the intermediate sum (n'' + n) and 'a' on the delay ( n')
always_comb begin
int i;
bit signed [WIDTH-1:0] d[2];
bit signed [WIDTH-1:0] e[2];
bit signed [WIDTH-1:0] f[2];
bit signed [WIDTH-1:0] h[2];
bit signed [WIDTH-1:0] s[2];
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff