git-svn-id: http://moon:8086/svn/vhdl/trunk@1411 cc03376c-175c-47c8-b038-4cd826a8556b
1068 lines
30 KiB
VHDL
1068 lines
30 KiB
VHDL
----------------------------------------------------------------------------------
|
|
-- Company:
|
|
-- Engineer:
|
|
--
|
|
-- Create Date: 11:30:30 08/27/2006
|
|
-- Design Name:
|
|
-- Module Name: ac97_test - Behavioral
|
|
-- Project Name:
|
|
-- Target Devices:
|
|
-- Tool versions:
|
|
-- Description:
|
|
--
|
|
-- Dependencies:
|
|
--
|
|
-- Revision:
|
|
-- Revision 0.01 - File Created
|
|
-- Additional Comments:
|
|
--
|
|
----------------------------------------------------------------------------------
|
|
library IEEE;
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
|
use IEEE.NUMERIC_STD.ALL;
|
|
use work.fixed_pkg.all;
|
|
use work.mix_pkg.all;
|
|
use work.cpu_pkg.all;
|
|
|
|
---- Uncomment the following library declaration if instantiating
|
|
---- any Xilinx primitives in this code.
|
|
library UNISIM;
|
|
use UNISIM.VComponents.all;
|
|
|
|
entity ac97_test is
|
|
Port (
|
|
sys_rst_n_in : in std_logic;
|
|
sys_clk_in : in std_logic;
|
|
sys_btn : in std_logic_vector(4 downto 0);
|
|
sys_dip : in std_logic_vector(7 downto 0);
|
|
sys_led : out std_logic_vector(8 downto 0);
|
|
sys_rx : in std_logic;
|
|
sys_tx : out std_logic;
|
|
sys_lcd_d : inout std_logic_vector(3 downto 0);
|
|
sys_lcd_e : out std_logic;
|
|
sys_lcd_rs : out std_logic;
|
|
sys_lcd_rw : out std_logic;
|
|
ac97_bit_clk : in STD_LOGIC;
|
|
ac97_sdata_in : in STD_LOGIC;
|
|
ac97_reset_n : out STD_LOGIC;
|
|
ac97_sdata_out : out STD_LOGIC;
|
|
ac97_sync : out STD_LOGIC
|
|
);
|
|
end ac97_test;
|
|
|
|
architecture Behavioral of ac97_test is
|
|
|
|
constant mix_nbits : integer := 18;
|
|
constant nco_nbits_wave : integer := 18;
|
|
constant nco_nbits_phase : integer := 16;
|
|
constant fir_bp_nbits : integer := 18;
|
|
constant fir_lp_nbits : integer := 18;
|
|
constant f : REAL := 1.0E3;
|
|
constant df : REAL := 100.0;
|
|
constant fa : REAL := 48.0E3;
|
|
|
|
constant nco_freq_word : integer := integer(f/fa*2.0**nco_nbits_phase);
|
|
constant nco_freq_inc : integer := integer(df/fa*2.0**nco_nbits_phase);
|
|
|
|
type stereo_t is (left, right);
|
|
type pcm_data_t is array (stereo_t) of signed(17 downto 0);
|
|
type stereo_bits_t is array (stereo_t) of std_logic;
|
|
|
|
------------------------------------------------------------------
|
|
COMPONENT singleshot
|
|
GENERIC (mode : integer);
|
|
PORT(
|
|
rst : IN std_logic;
|
|
clk : IN std_logic;
|
|
input : IN std_logic;
|
|
output : OUT std_logic
|
|
);
|
|
END COMPONENT;
|
|
|
|
COMPONENT ac_io
|
|
Port (
|
|
rst : in std_logic;
|
|
clk : in std_logic;
|
|
ready : out std_logic;
|
|
sync_strobe : out unsigned(0 to 2);
|
|
slot_valid : out unsigned(0 to 12);
|
|
stat_addr : out unsigned (19 downto 0);
|
|
stat_data : out unsigned (19 downto 0);
|
|
rx_pcm_addr : in unsigned (3 downto 0);
|
|
rx_pcm_data : out unsigned (19 downto 0);
|
|
cmd_addr : in unsigned(19 downto 0);
|
|
cmd_data : in unsigned(19 downto 0);
|
|
cmd_we : in std_logic;
|
|
tx_pcm_addr : in unsigned(3 downto 0);
|
|
tx_pcm_data : in unsigned(19 downto 0);
|
|
tx_pcm_we : in std_logic;
|
|
ac_sdata_in : in std_logic;
|
|
ac_bit_clk : in std_logic;
|
|
ac_reset_n : out std_logic;
|
|
ac_sdata_out : out std_logic;
|
|
ac_ssync : out std_logic
|
|
);
|
|
END COMPONENT;
|
|
|
|
SIGNAL sync_strobe : unsigned(0 to 2);
|
|
SIGNAL slot_valid : unsigned(0 to 12);
|
|
SIGNAL cmd_we : std_logic;
|
|
SIGNAL cmd_addr : unsigned(19 downto 0);
|
|
SIGNAL cmd_data : unsigned(19 downto 0);
|
|
SIGNAL stat_addr : unsigned(19 downto 0);
|
|
SIGNAL stat_data : unsigned(19 downto 0);
|
|
SIGNAL tx_pcm_addr : unsigned(3 downto 0);
|
|
SIGNAL tx_pcm_data : unsigned(19 downto 0);
|
|
SIGNAL rx_pcm_addr : unsigned(3 downto 0);
|
|
SIGNAL tx_pcm_we : std_logic;
|
|
SIGNAL rx_pcm_data : unsigned(19 downto 0);
|
|
|
|
COMPONENT syn_nco
|
|
PORT(
|
|
rst : in std_logic;
|
|
clk : in std_logic;
|
|
pacc_clr : in std_logic;
|
|
pacc_inc : in std_logic;
|
|
freq_in : in unsigned(nco_nbits_phase-1 downto 0);
|
|
freq_load : in std_logic;
|
|
phase_in : in unsigned(nco_nbits_phase-1 downto 0);
|
|
phase_load : in std_logic;
|
|
phase_out : out unsigned(nco_nbits_phase-1 downto 0);
|
|
wave_out_i : out signed(nco_nbits_wave-1 downto 0);
|
|
wave_out_q : out signed(nco_nbits_wave-1 downto 0);
|
|
out_valid : out std_logic
|
|
);
|
|
END COMPONENT;
|
|
|
|
SIGNAL nco_pacc_clr : std_logic;
|
|
SIGNAL nco_pacc_inc : std_logic;
|
|
SIGNAL nco_freq_in : unsigned(nco_nbits_phase-1 downto 0);
|
|
SIGNAL nco_freq_load : std_logic;
|
|
SIGNAL nco_phase_in : unsigned(nco_nbits_phase-1 downto 0);
|
|
SIGNAL nco_phase_load : std_logic;
|
|
SIGNAL nco_phase_out : unsigned(nco_nbits_phase-1 downto 0);
|
|
signal pcm_nco_data : pcm_data_t;
|
|
SIGNAL nco_out_valid : std_logic;
|
|
|
|
COMPONENT cpu_embedded
|
|
Port (
|
|
rst : in STD_LOGIC;
|
|
clk : in STD_LOGIC;
|
|
ce : in STD_LOGIC;
|
|
int_in : in STD_LOGIC;
|
|
int_ack : out STD_LOGIC;
|
|
xmem_we : out STD_LOGIC;
|
|
xmem_re : out STD_LOGIC;
|
|
xmem_din : in unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
|
xmem_dout : out unsigned (DMEM_DATA_WIDTH-1 downto 0);
|
|
xmem_addr : out unsigned (DMEM_ADDR_WIDTH-1 downto 0);
|
|
io_sel : out STD_LOGIC
|
|
);
|
|
END COMPONENT;
|
|
|
|
signal cpu_ce : std_logic;
|
|
signal cpu_int_in : std_logic;
|
|
signal cpu_int_ack : std_logic;
|
|
signal cpu_din : dmem_data_t;
|
|
signal cpu_dout : dmem_data_t;
|
|
signal cpu_addr : dmem_addr_t;
|
|
signal cpu_we : std_logic;
|
|
signal cpu_re : std_logic;
|
|
signal cpu_io_sel : std_logic;
|
|
|
|
COMPONENT xrom
|
|
Port (
|
|
clk : in STD_LOGIC;
|
|
ce : in STD_LOGIC;
|
|
addr : in dmem_addr_t;
|
|
dout : out dmem_data_t
|
|
);
|
|
END COMPONENT;
|
|
signal xrom_data : dmem_data_t;
|
|
|
|
COMPONENT syn_fir_bandpass
|
|
PORT(
|
|
rst : in std_logic;
|
|
clk : in std_logic;
|
|
ready_i : out std_logic;
|
|
x_valid_i : in std_logic;
|
|
x_din_i : in signed(fir_bp_nbits-1 downto 0);
|
|
y_valid_i : out std_logic;
|
|
y_dout_i : out signed(fir_bp_nbits-1 downto 0);
|
|
ready_q : out std_logic;
|
|
x_valid_q : in std_logic;
|
|
x_din_q : in signed(fir_bp_nbits-1 downto 0);
|
|
y_valid_q : out std_logic;
|
|
y_dout_q : out signed(fir_bp_nbits-1 downto 0)
|
|
);
|
|
END COMPONENT;
|
|
|
|
signal fir_bp_ready : stereo_bits_t;
|
|
signal fir_bp_din_we : stereo_bits_t;
|
|
signal fir_bp_dout_valid : stereo_bits_t;
|
|
signal fir_bp_din : pcm_data_t;
|
|
signal fir_bp_dout : pcm_data_t;
|
|
|
|
COMPONENT syn_fir_lowpass
|
|
PORT(
|
|
rst : in std_logic;
|
|
clk : in std_logic;
|
|
ready_i : out std_logic;
|
|
x_valid_i : in std_logic;
|
|
x_din_i : in signed(fir_lp_nbits-1 downto 0);
|
|
y_valid_i : out std_logic;
|
|
y_dout_i : out signed(fir_lp_nbits-1 downto 0);
|
|
ready_q : out std_logic;
|
|
x_valid_q : in std_logic;
|
|
x_din_q : in signed(fir_lp_nbits-1 downto 0);
|
|
y_valid_q : out std_logic;
|
|
y_dout_q : out signed(fir_lp_nbits-1 downto 0)
|
|
);
|
|
END COMPONENT;
|
|
|
|
signal fir_lp_ready : stereo_bits_t;
|
|
signal fir_lp_din_we : stereo_bits_t;
|
|
signal fir_lp_dout_valid : stereo_bits_t;
|
|
signal fir_lp_din : pcm_data_t;
|
|
signal fir_lp_dout : pcm_data_t;
|
|
|
|
COMPONENT mix_cpx
|
|
GENERIC
|
|
(
|
|
nbits_in : integer;
|
|
nbits_in_frac : integer;
|
|
nbits_out : integer;
|
|
nbits_out_frac : integer;
|
|
nbits_scale_z : integer;
|
|
has_in_reg : boolean;
|
|
has_pipe_reg : boolean;
|
|
has_out_reg : boolean;
|
|
rounding : boolean;
|
|
saturating : boolean
|
|
);
|
|
PORT
|
|
(
|
|
srst : in std_logic;
|
|
clk : in std_logic;
|
|
in_valid : in std_logic;
|
|
x_re_in : in sfixed(sproto(mix_nbits, mix_nbits)'high downto sproto(mix_nbits, mix_nbits)'low);
|
|
x_im_in : in sfixed(sproto(mix_nbits, mix_nbits)'high downto sproto(mix_nbits, mix_nbits)'low);
|
|
y_re_in : in sfixed(sproto(mix_nbits, mix_nbits)'high downto sproto(mix_nbits, mix_nbits)'low);
|
|
y_im_in : in sfixed(sproto(mix_nbits, mix_nbits)'high downto sproto(mix_nbits, mix_nbits)'low);
|
|
out_valid : out std_logic;
|
|
z_re_out : out sfixed(sproto(mix_nbits, mix_nbits)'high downto sproto(mix_nbits, mix_nbits)'low);
|
|
z_im_out : out sfixed(sproto(mix_nbits, mix_nbits)'high downto sproto(mix_nbits, mix_nbits)'low)
|
|
);
|
|
END COMPONENT;
|
|
|
|
constant mix_nbits_scale_z : integer := 1;
|
|
signal mix_x_re : sfixed(sproto(mix_nbits, mix_nbits)'high downto sproto(mix_nbits, mix_nbits)'low);
|
|
signal mix_x_im : sfixed(sproto(mix_nbits, mix_nbits)'high downto sproto(mix_nbits, mix_nbits)'low);
|
|
signal mix_y_re : sfixed(sproto(mix_nbits, mix_nbits)'high downto sproto(mix_nbits, mix_nbits)'low);
|
|
signal mix_y_im : sfixed(sproto(mix_nbits, mix_nbits)'high downto sproto(mix_nbits, mix_nbits)'low);
|
|
signal mix_z_re : sfixed(sproto(mix_nbits, mix_nbits)'high downto sproto(mix_nbits, mix_nbits)'low);
|
|
signal mix_z_im : sfixed(sproto(mix_nbits, mix_nbits)'high downto sproto(mix_nbits, mix_nbits)'low);
|
|
signal mix_in_valid : std_logic;
|
|
signal mix_out_valid : std_logic;
|
|
|
|
COMPONENT lcd_port
|
|
PORT (
|
|
rst : in std_logic;
|
|
clk : in std_logic;
|
|
we : in std_logic;
|
|
din : in unsigned(7 downto 0);
|
|
dout : out unsigned(7 downto 0);
|
|
lcd_d : inout std_logic_vector(3 downto 0);
|
|
lcd_e : out std_logic;
|
|
lcd_rs : out std_logic;
|
|
lcd_rw : out std_logic
|
|
);
|
|
END COMPONENT;
|
|
|
|
signal cpu_lcd_in_reg, cpu_lcd_out_reg : unsigned(DMEM_DATA_WIDTH-1 downto 0);
|
|
signal cpu_lcd_we : std_logic;
|
|
|
|
------------------------------------------------------------------
|
|
-- X"1F400", -- W: DAC rate 8000Hz
|
|
-- X"AC440", -- W: DAC rate 44100Hz
|
|
------------------------------------------------------------------
|
|
|
|
subtype cmd_cnt_t is integer range 0 to 9;
|
|
type state_t is (st_reset, st_status_write, st_status_read, st_config, st_pcm_in, st_pcm_in3, st_pcm_in4, st_pcm_out, st_pcm_out3, st_pcm_out4);
|
|
type mem_t is array (natural range <>) of unsigned(19 downto 0);
|
|
|
|
constant config_rom_addr : mem_t (cmd_cnt_t'low to cmd_cnt_t'high) :=
|
|
(
|
|
X"A6000", -- R: Status register
|
|
X"2A000", -- W: Extended Audio CTRL/STATUS
|
|
X"1A000", -- W: Record select
|
|
X"1C000", -- W: Record gain
|
|
X"2C000", -- W: PCM DAC rate
|
|
X"32000", -- W: PCM ADC rate
|
|
X"20000", -- W: General purpose
|
|
X"02000", -- W: Master volume
|
|
X"04000", -- W: Headphone volume
|
|
X"18000" -- W: PCM volume
|
|
);
|
|
|
|
constant config_rom_data : mem_t (cmd_cnt_t'low to cmd_cnt_t'high) :=
|
|
(
|
|
X"00000", -- R: Status register
|
|
X"00010", -- W: VRA=1
|
|
X"04040", -- W: Record source = LINE_IN
|
|
X"00000", -- W: Record gain = 0dB
|
|
X"BB800", -- W: DAC rate 48000Hz
|
|
X"BB800", -- W: ADC rate 48000Hz
|
|
X"80000", -- W: POP=1
|
|
X"00000", -- W: Master volume = 0dB
|
|
X"00000", -- W: Headphone volume = 0dB, muted
|
|
X"0A0A0" -- W: PCM volume = -3dB
|
|
);
|
|
|
|
signal rst, clk : std_logic;
|
|
signal acio_ready : std_logic;
|
|
signal nco_freq_set : unsigned(nco_nbits_phase-1 downto 0);
|
|
signal pcm_rom_data : signed(19 downto 0);
|
|
signal pcm_rom_addr : unsigned(9 downto 0);
|
|
signal pcm_active, cmd_active : std_logic;
|
|
signal state, nextstate : state_t;
|
|
signal cmd_cnt : cmd_cnt_t;
|
|
signal cmd_cnt_rst, cmd_cnt_en : std_logic;
|
|
signal ac_reset_n : std_logic;
|
|
signal ac_rst : std_logic;
|
|
signal ac_ssync : std_logic;
|
|
signal pcm_request, pcm_request_set, pcm_request_ack : std_logic;
|
|
signal started_up : std_logic := '1';
|
|
signal cpu_freq, cpu_cmd_addr, cpu_cmd_data, cpu_stat_addr, cpu_stat_data : unsigned(15 downto 0);
|
|
signal cpu_mix_dc_adj_left, cpu_mix_dc_adj_right, cpu_pcmin_dc_adj_left, cpu_pcmin_dc_adj_right : unsigned(15 downto 0);
|
|
|
|
|
|
subtype low is unsigned(7 downto 0);
|
|
subtype high is unsigned(15 downto 8);
|
|
|
|
signal pcm_in_data : pcm_data_t;
|
|
signal pcm_out_data : pcm_data_t;
|
|
|
|
signal pcm_in_data_we, pcm_in_valid : stereo_bits_t;
|
|
|
|
type pcmout_mode_t is (PCMOUT_TONE, PCMOUT_LOOPTHROUGH, PCMOUT_FILTERED, PCMOUT_MIXER, PCMOUT_FM, PCMOUT_BASEBAND);
|
|
signal pcmout_mode : pcmout_mode_t;
|
|
signal pcm_table_data : unsigned(19 downto 0);
|
|
signal cpu_cmd_access, cpu_freq_access, cpu_cmd_ready, cpu_stat_ready : std_logic;
|
|
signal cpu_led_reg, cpu_btn_reg, cpu_dip_reg, cpu_pcmmode_reg : unsigned(DMEM_DATA_WIDTH-1 downto 0);
|
|
signal fsm_cmd_we, cpu_cmd_we, cmd_access_is_fsm : std_logic;
|
|
|
|
------------------------------------------------------------------
|
|
function GetRequest(slot1 : unsigned) return unsigned is
|
|
variable res : unsigned(3 to 12);
|
|
begin
|
|
res := (others => '0');
|
|
for i in res'range loop
|
|
res(i) := not slot1(14-i);
|
|
end loop;
|
|
return res;
|
|
|
|
end GetRequest;
|
|
|
|
begin
|
|
|
|
------------------------------------------------------------------
|
|
cmd_data <= config_rom_data(cmd_cnt) when cmd_access_is_fsm = '1' else (cpu_cmd_data & "0000");
|
|
cmd_addr <= config_rom_addr(cmd_cnt) when cmd_access_is_fsm = '1' else (cpu_cmd_addr & "0000");
|
|
|
|
ac_rst <= not ac_reset_n;
|
|
ac97_reset_n <= ac_reset_n;
|
|
ac97_sync <= ac_ssync;
|
|
|
|
sys_tx <= sys_rx;
|
|
|
|
cpu_ce <= '1';
|
|
clk <= sys_clk_in;
|
|
rst <= not (started_up and sys_rst_n_in);
|
|
-- rst <= not (sys_rst_n_in);
|
|
|
|
cpu_int_in <= sync_strobe(0);
|
|
|
|
fir_bp_din_we(left) <= pcm_in_valid(left) and fir_bp_ready(left);
|
|
fir_bp_din_we(right) <= pcm_in_valid(right) and fir_bp_ready(right);
|
|
fir_bp_din(left to right) <= pcm_in_data(left to right);
|
|
|
|
fir_lp_din_we(left) <= mix_out_valid and fir_lp_ready(left);
|
|
fir_lp_din_we(right) <= mix_out_valid and fir_lp_ready(right);
|
|
fir_lp_din(left) <= to_signed(mix_z_re);
|
|
fir_lp_din(right) <= to_signed(mix_z_im);
|
|
|
|
cmd_we <= fsm_cmd_we or cpu_cmd_we;
|
|
|
|
------------------------------------------------------------------
|
|
proc_led_btn:
|
|
process (rst, clk)
|
|
begin
|
|
if rising_edge(clk) then
|
|
cpu_btn_reg <= "000" & unsigned(sys_btn);
|
|
cpu_dip_reg <= unsigned(sys_dip);
|
|
if rst = '1' then
|
|
sys_led <= (others => '0');
|
|
else
|
|
sys_led(7 downto 0) <= STD_LOGIC_VECTOR(cpu_led_reg);
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
------------------------------------------------------------------
|
|
host_din : process (acio_ready, sync_strobe, slot_valid, stat_addr, stat_data, state, cmd_cnt, pcm_request, pcm_out_data)
|
|
variable request : unsigned(3 to 12);
|
|
variable rx_frame_valid : std_logic;
|
|
variable sync_frame, sync_status, sync_tx : std_logic;
|
|
|
|
begin
|
|
request := GetRequest(stat_addr);
|
|
rx_frame_valid := slot_valid(0);
|
|
sync_frame := sync_strobe(0);
|
|
sync_status := sync_strobe(1);
|
|
sync_tx := sync_strobe(2);
|
|
|
|
cmd_cnt_rst <= '0';
|
|
cmd_cnt_en <= '0';
|
|
fsm_cmd_we <= '0';
|
|
tx_pcm_we <= '0';
|
|
tx_pcm_addr <= to_unsigned(3, tx_pcm_addr'length);
|
|
tx_pcm_data <= to_unsigned(0, tx_pcm_data'length);
|
|
|
|
rx_pcm_addr <= to_unsigned(3, rx_pcm_addr'length);
|
|
|
|
nextstate <= state;
|
|
pcm_active <= '0';
|
|
cmd_active <= '0';
|
|
pcm_request_set <= '0';
|
|
pcm_request_ack <= '0';
|
|
pcm_in_data_we <= (others => '0');
|
|
|
|
nco_pacc_inc <= '0';
|
|
nco_pacc_clr <= '0';
|
|
nco_phase_in <= (others => '0');
|
|
nco_phase_load <= '0';
|
|
|
|
cmd_access_is_fsm <= '0';
|
|
case state is
|
|
|
|
when st_reset =>
|
|
cmd_access_is_fsm <= '1';
|
|
cmd_cnt_rst <= '1';
|
|
if rx_frame_valid = '1' and sync_status = '1' and acio_ready = '1' then
|
|
nextstate <= st_status_write;
|
|
end if;
|
|
|
|
when st_status_write =>
|
|
cmd_access_is_fsm <= '1';
|
|
if rx_frame_valid = '1' and sync_tx = '1' then
|
|
fsm_cmd_we <= '1';
|
|
nextstate <= st_status_read;
|
|
end if;
|
|
|
|
when st_status_read =>
|
|
cmd_access_is_fsm <= '1';
|
|
if sync_status = '1' then
|
|
if slot_valid(1 to 2) = "11" then
|
|
if stat_data(7 downto 4) = "1111" then
|
|
cmd_cnt_en <= '1';
|
|
nextstate <= st_config;
|
|
else
|
|
nextstate <= st_status_write;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
|
|
when st_config =>
|
|
cmd_access_is_fsm <= '1';
|
|
cmd_active <= '1';
|
|
|
|
if sync_tx = '1' then
|
|
cmd_cnt_en <= '1';
|
|
fsm_cmd_we <= '1';
|
|
if cmd_cnt = cmd_cnt_t'high then
|
|
nextstate <= st_pcm_in;
|
|
end if;
|
|
end if;
|
|
|
|
when st_pcm_in =>
|
|
if rx_frame_valid = '1' and sync_frame = '1' then
|
|
nextstate <= st_pcm_in3;
|
|
end if;
|
|
|
|
when st_pcm_in3 =>
|
|
nextstate <= st_pcm_in4;
|
|
rx_pcm_addr <= to_unsigned(3, rx_pcm_addr'length);
|
|
if slot_valid(3) = '1' then
|
|
pcm_in_data_we(left) <= '1';
|
|
end if;
|
|
|
|
when st_pcm_in4 =>
|
|
nextstate <= st_pcm_out;
|
|
rx_pcm_addr <= to_unsigned(4, rx_pcm_addr'length);
|
|
if slot_valid(4) = '1' then
|
|
pcm_in_data_we(right) <= '1';
|
|
end if;
|
|
|
|
when st_pcm_out =>
|
|
pcm_active <= '1';
|
|
if rx_frame_valid = '1' and sync_status = '1' then
|
|
if request(3) = '1' and request(4) = '1' then
|
|
pcm_request_set <= '1';
|
|
nco_pacc_inc <= '1';
|
|
end if;
|
|
end if;
|
|
if pcm_request = '1' and sync_tx = '1' then
|
|
nextstate <= st_pcm_out3;
|
|
end if;
|
|
|
|
when st_pcm_out3 =>
|
|
tx_pcm_data <= unsigned(pcm_out_data(left)) & "00";
|
|
pcm_active <= '1';
|
|
tx_pcm_addr <= to_unsigned(3, tx_pcm_addr'length);
|
|
tx_pcm_we <= '1';
|
|
pcm_request_ack <= '1';
|
|
nextstate <= st_pcm_out4;
|
|
|
|
when st_pcm_out4 =>
|
|
tx_pcm_data <= unsigned(pcm_out_data(right)) & "00";
|
|
pcm_active <= '1';
|
|
tx_pcm_addr <= to_unsigned(4, tx_pcm_addr'length);
|
|
tx_pcm_we <= '1';
|
|
nextstate <= st_pcm_in;
|
|
|
|
when others =>
|
|
nextstate <= st_reset;
|
|
|
|
end case;
|
|
|
|
end process;
|
|
|
|
proc_fsm_next:
|
|
process (rst, clk, nextstate)
|
|
begin
|
|
if rst = '1' then
|
|
state <= st_reset;
|
|
elsif rising_edge(clk) then
|
|
state <= nextstate;
|
|
end if;
|
|
end process;
|
|
|
|
-------------------------------------------------------------
|
|
-- proc_pcm_in
|
|
-------------------------------------------------------------
|
|
proc_pcm_in:
|
|
process (rst, clk, pcm_in_data_we, rx_pcm_data)
|
|
variable dc_adj : pcm_data_t;
|
|
begin
|
|
dc_adj(left) := resize(signed(cpu_pcmin_dc_adj_left), dc_adj(left)'length);
|
|
dc_adj(right) := resize(signed(cpu_pcmin_dc_adj_right), dc_adj(right)'length);
|
|
|
|
if rst = '1' then
|
|
for i in pcm_in_data'range loop
|
|
dc_adj(i) := (others => '0');
|
|
pcm_in_data(i) <= (others => '0');
|
|
pcm_in_valid(i) <= '0';
|
|
end loop;
|
|
elsif rising_edge(clk) then
|
|
for i in pcm_in_data'range loop
|
|
pcm_in_valid(i) <= '0';
|
|
end loop;
|
|
for i in pcm_in_data'range loop
|
|
if pcm_in_data_we(i) = '1' then
|
|
pcm_in_valid(i) <= '1';
|
|
pcm_in_data(i) <= dc_adj(i) + signed(rx_pcm_data(19 downto 2));
|
|
end if;
|
|
end loop;
|
|
end if;
|
|
end process;
|
|
|
|
-------------------------------------------------------------
|
|
-- proc_mix_input
|
|
-------------------------------------------------------------
|
|
proc_mix_input:
|
|
process (rst, clk)
|
|
begin
|
|
|
|
if rst = '1' then
|
|
mix_in_valid <= '0';
|
|
mix_x_re <= to_sfixed(0.0, mix_x_re);
|
|
mix_x_im <= to_sfixed(0.0, mix_x_im);
|
|
elsif rising_edge(clk) then
|
|
mix_in_valid <= '0';
|
|
if fir_bp_dout_valid(right) = '1' then
|
|
mix_in_valid <= '1';
|
|
mix_x_re <= sfixed(signed(cpu_mix_dc_adj_left) + fir_bp_dout(left));
|
|
mix_x_im <= sfixed(signed(cpu_mix_dc_adj_right) + fir_bp_dout(right));
|
|
end if;
|
|
mix_y_re <= sfixed(pcm_nco_data(left));
|
|
mix_y_im <= sfixed(pcm_nco_data(right));
|
|
end if;
|
|
end process;
|
|
|
|
-------------------------------------------------------------
|
|
-- proc_pcmout_mode_mapper
|
|
-------------------------------------------------------------
|
|
proc_pcmout_mode_mapper:
|
|
process (cpu_pcmmode_reg)
|
|
begin
|
|
case cpu_pcmmode_reg is
|
|
when X"00" =>
|
|
pcmout_mode <= PCMOUT_LOOPTHROUGH;
|
|
when X"01" =>
|
|
pcmout_mode <= PCMOUT_FILTERED;
|
|
when X"02" =>
|
|
pcmout_mode <= PCMOUT_TONE;
|
|
when X"03" =>
|
|
pcmout_mode <= PCMOUT_MIXER;
|
|
when X"04" =>
|
|
pcmout_mode <= PCMOUT_FM;
|
|
when X"05" =>
|
|
pcmout_mode <= PCMOUT_BASEBAND;
|
|
when others =>
|
|
pcmout_mode <= PCMOUT_LOOPTHROUGH;
|
|
end case;
|
|
end process;
|
|
|
|
-------------------------------------------------------------
|
|
-- proc_pcm_out_mux
|
|
-------------------------------------------------------------
|
|
proc_pcm_out_mux:
|
|
process (clk)
|
|
begin
|
|
if rising_edge(clk) then
|
|
case pcmout_mode is
|
|
when PCMOUT_TONE | PCMOUT_FM =>
|
|
pcm_out_data(left to right) <= pcm_nco_data(left to right);
|
|
when PCMOUT_LOOPTHROUGH =>
|
|
pcm_out_data(left to right) <= pcm_in_data(left to right);
|
|
when PCMOUT_FILTERED =>
|
|
pcm_out_data(left to right) <= fir_bp_dout(left to right);
|
|
when PCMOUT_MIXER =>
|
|
pcm_out_data(left) <= to_signed(mix_z_re);
|
|
pcm_out_data(right) <= to_signed(mix_z_im);
|
|
when PCMOUT_BASEBAND =>
|
|
pcm_out_data(left to right) <= fir_lp_dout(left to right);
|
|
when others =>
|
|
pcm_out_data(left to right) <= pcm_nco_data(left to right);
|
|
end case;
|
|
end if;
|
|
end process;
|
|
|
|
-------------------------------------------------------------
|
|
-- proc_cmd_count
|
|
-------------------------------------------------------------
|
|
proc_cmd_count:
|
|
process (clk)
|
|
begin
|
|
if rising_edge(clk) then
|
|
if cmd_cnt_rst = '1' then
|
|
cmd_cnt <= cmd_cnt_t'low;
|
|
elsif cmd_cnt_en = '1' then
|
|
if cmd_cnt /= cmd_cnt_t'high then
|
|
cmd_cnt <= cmd_cnt + 1;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-------------------------------------------------------------
|
|
-- proc_freq_mod
|
|
-------------------------------------------------------------
|
|
proc_freq_mod:
|
|
process (clk)
|
|
begin
|
|
if rising_edge(clk) then
|
|
if rst = '1' then
|
|
nco_freq_set <= to_unsigned(nco_freq_word, nco_nbits_phase);
|
|
elsif cpu_freq_access = '1' then
|
|
nco_freq_set <= cpu_freq;
|
|
end if;
|
|
if pcmout_mode = PCMOUT_FM then
|
|
nco_freq_in <= unsigned(fir_bp_dout(left)(nco_freq_in'left downto 2) + signed(nco_freq_set));
|
|
else
|
|
nco_freq_in <= nco_freq_set;
|
|
end if;
|
|
nco_freq_load <= fir_bp_dout_valid(left);
|
|
end if;
|
|
end process;
|
|
|
|
-------------------------------------------------------------
|
|
-- proc_cpu_flags
|
|
-------------------------------------------------------------
|
|
proc_cpu_stat_reg_control:
|
|
process (clk, sync_strobe, slot_valid)
|
|
variable rx_frame_valid : std_logic;
|
|
variable sync_frame, sync_status, sync_tx : std_logic;
|
|
begin
|
|
rx_frame_valid := slot_valid(0);
|
|
sync_frame := sync_strobe(0);
|
|
sync_status := sync_strobe(1);
|
|
sync_tx := sync_strobe(2);
|
|
|
|
if rising_edge(clk) then
|
|
if rst = '1' then
|
|
cpu_cmd_ready <= '0';
|
|
cpu_stat_ready <= '0';
|
|
cpu_stat_addr <= (others => '0');
|
|
cpu_stat_data <= (others => '0');
|
|
else
|
|
cpu_cmd_we <= '0';
|
|
if cpu_cmd_access = '1' then
|
|
cpu_cmd_ready <= '0';
|
|
cpu_stat_ready <= '0';
|
|
end if;
|
|
|
|
if rx_frame_valid = '1' then
|
|
if sync_tx = '1' then
|
|
if cpu_cmd_ready = '0' then
|
|
cpu_cmd_ready <= '1';
|
|
cpu_cmd_we <= '1';
|
|
end if;
|
|
end if;
|
|
if sync_status = '1' and slot_valid(1 to 2) = "11" then
|
|
cpu_stat_ready <= '1';
|
|
cpu_stat_addr <= stat_addr(19 downto 4);
|
|
cpu_stat_data <= stat_data(19 downto 4);
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
|
|
end process;
|
|
|
|
-------------------------------------------------------------
|
|
-- proc_cpu_dout_reg
|
|
-------------------------------------------------------------
|
|
proc_cpu_dout_reg:
|
|
process (clk)
|
|
variable addr : dmem_addr_t;
|
|
begin
|
|
if rising_edge(clk) then
|
|
if rst = '1' then
|
|
cpu_led_reg <= (others => '0');
|
|
cpu_pcmmode_reg <= (others => '0');
|
|
cpu_freq <= (others => '0');
|
|
cpu_cmd_addr <= (others => '0');
|
|
cpu_cmd_data <= (others => '0');
|
|
cpu_lcd_out_reg <= (others => '0');
|
|
cpu_mix_dc_adj_left <= (others => '0');
|
|
cpu_mix_dc_adj_right <= (others => '0');
|
|
cpu_pcmin_dc_adj_left <= (others => '0');
|
|
cpu_pcmin_dc_adj_right <= (others => '0');
|
|
else
|
|
addr := cpu_addr;
|
|
cpu_cmd_access <= '0';
|
|
cpu_freq_access <= '0';
|
|
cpu_lcd_we <= '0';
|
|
if cpu_we = '1' and cpu_io_sel = '1' then
|
|
case addr is
|
|
when X"00" =>
|
|
cpu_led_reg <= cpu_dout;
|
|
when X"01" =>
|
|
cpu_pcmmode_reg <= cpu_dout;
|
|
when X"02" =>
|
|
cpu_freq_access <= '1';
|
|
cpu_freq(low'range) <= cpu_dout;
|
|
when X"03" =>
|
|
cpu_freq(high'range) <= cpu_dout;
|
|
when X"04" =>
|
|
cpu_cmd_addr(low'range) <= cpu_dout;
|
|
when X"05" =>
|
|
cpu_cmd_addr(high'range) <= cpu_dout;
|
|
when X"06" =>
|
|
cpu_cmd_access <= '1';
|
|
cpu_cmd_data(low'range) <= cpu_dout;
|
|
when X"07" =>
|
|
cpu_cmd_data(high'range) <= cpu_dout;
|
|
when X"08" =>
|
|
cpu_lcd_we <= '1';
|
|
cpu_lcd_out_reg <= cpu_dout;
|
|
when X"09" =>
|
|
cpu_mix_dc_adj_left(low'range) <= cpu_dout;
|
|
when X"0A" =>
|
|
cpu_mix_dc_adj_left(high'range) <= cpu_dout;
|
|
when X"0B" =>
|
|
cpu_mix_dc_adj_right(low'range) <= cpu_dout;
|
|
when X"0C" =>
|
|
cpu_mix_dc_adj_right(high'range) <= cpu_dout;
|
|
when X"0D" =>
|
|
cpu_pcmin_dc_adj_left(low'range) <= cpu_dout;
|
|
when X"0E" =>
|
|
cpu_pcmin_dc_adj_left(high'range) <= cpu_dout;
|
|
when X"0F" =>
|
|
cpu_pcmin_dc_adj_right(low'range) <= cpu_dout;
|
|
when X"10" =>
|
|
cpu_pcmin_dc_adj_right(high'range) <= cpu_dout;
|
|
when others => null;
|
|
end case;
|
|
end if;
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-------------------------------------------------------------
|
|
-- proc_cpu_din_reg
|
|
-------------------------------------------------------------
|
|
proc_cpu_din_reg:
|
|
process (clk, cpu_io_sel, xrom_data)
|
|
variable mix_xre, mix_xim : signed (mix_nbits-1 downto 0);
|
|
variable mix_yre, mix_yim : signed (mix_nbits-1 downto 0);
|
|
variable addr : dmem_addr_t;
|
|
begin
|
|
|
|
mix_xre := to_signed(mix_x_re);
|
|
mix_xim := to_signed(mix_x_im);
|
|
mix_yre := to_signed(mix_y_re);
|
|
mix_yim := to_signed(mix_y_im);
|
|
|
|
if rising_edge(clk) then
|
|
addr := cpu_addr;
|
|
end if;
|
|
|
|
if cpu_io_sel = '0' then
|
|
cpu_din <= xrom_data;
|
|
else
|
|
case addr is
|
|
when X"00" =>
|
|
cpu_din <= cpu_led_reg;
|
|
when X"01" =>
|
|
cpu_din <= cpu_pcmmode_reg;
|
|
when X"02" =>
|
|
cpu_din <= cpu_freq(low'range);
|
|
when X"03" =>
|
|
cpu_din <= cpu_freq(high'range);
|
|
when X"04" =>
|
|
cpu_din <= cpu_stat_addr(low'range);
|
|
when X"05" =>
|
|
cpu_din <= cpu_stat_addr(high'range);
|
|
when X"06" =>
|
|
cpu_din <= cpu_stat_data(low'range);
|
|
when X"07" =>
|
|
cpu_din <= cpu_stat_data(high'range);
|
|
when X"08" =>
|
|
cpu_din <= cpu_lcd_in_reg;
|
|
when X"09" =>
|
|
cpu_din <= cpu_mix_dc_adj_left(low'range);
|
|
when X"0A" =>
|
|
cpu_din <= cpu_mix_dc_adj_left(high'range);
|
|
when X"0B" =>
|
|
cpu_din <= cpu_mix_dc_adj_right(low'range);
|
|
when X"0C" =>
|
|
cpu_din <= cpu_mix_dc_adj_right(high'range);
|
|
when X"0D" =>
|
|
cpu_din <= cpu_pcmin_dc_adj_left(low'range);
|
|
when X"0E" =>
|
|
cpu_din <= cpu_pcmin_dc_adj_left(high'range);
|
|
when X"0F" =>
|
|
cpu_din <= cpu_pcmin_dc_adj_right(low'range);
|
|
when X"10" =>
|
|
cpu_din <= cpu_pcmin_dc_adj_right(high'range);
|
|
when X"80" =>
|
|
cpu_din <= cpu_btn_reg;
|
|
when X"81" =>
|
|
cpu_din <= cpu_dip_reg;
|
|
when X"82" =>
|
|
cpu_din <= dmem_data_t(pcm_in_data(left)(low'range));
|
|
when X"83" =>
|
|
cpu_din <= dmem_data_t(pcm_in_data(left)(high'range));
|
|
when X"84" =>
|
|
cpu_din <= dmem_data_t(pcm_in_data(right)(low'range));
|
|
when X"85" =>
|
|
cpu_din <= dmem_data_t(pcm_in_data(right)(high'range));
|
|
when X"86" =>
|
|
cpu_din <= dmem_data_t(mix_xre(low'range));
|
|
when X"87" =>
|
|
cpu_din <= dmem_data_t(mix_xre(high'range));
|
|
when X"88" =>
|
|
cpu_din <= dmem_data_t(mix_xim(low'range));
|
|
when X"89" =>
|
|
cpu_din <= dmem_data_t(mix_xim(high'range));
|
|
when X"8A" =>
|
|
cpu_din <= dmem_data_t(mix_yre(low'range));
|
|
when X"8B" =>
|
|
cpu_din <= dmem_data_t(mix_yre(high'range));
|
|
when X"8C" =>
|
|
cpu_din <= dmem_data_t(mix_yim(low'range));
|
|
when X"8D" =>
|
|
cpu_din <= dmem_data_t(mix_yim(high'range));
|
|
when X"A0" =>
|
|
cpu_din <= "0000" & (fir_bp_ready(left) and fir_bp_ready(right)) & cpu_stat_ready & cpu_cmd_ready & (pcm_active and acio_ready and slot_valid(0));
|
|
when others =>
|
|
if addr(0) = '0' then
|
|
cpu_din <= X"EF";
|
|
else
|
|
cpu_din <= X"BE";
|
|
end if;
|
|
end case;
|
|
end if;
|
|
|
|
end process;
|
|
-------------------------------------------------------------
|
|
proc_pcm_request:
|
|
process (clk, pcm_request_set, pcm_request_ack)
|
|
begin
|
|
if rising_edge(clk) then
|
|
if pcm_request_ack = '1' or rst = '1' then
|
|
pcm_request <= '0';
|
|
elsif pcm_request_set = '1' then
|
|
pcm_request <= '1';
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
------------------------------------------------------------------
|
|
-- Instantiate the Unit Under Test (UUT)
|
|
inst_ac_io: ac_io PORT MAP(
|
|
rst => rst,
|
|
clk => clk,
|
|
ready => acio_ready,
|
|
sync_strobe => sync_strobe,
|
|
slot_valid => slot_valid,
|
|
stat_addr => stat_addr,
|
|
stat_data => stat_data,
|
|
rx_pcm_addr => rx_pcm_addr,
|
|
rx_pcm_data => rx_pcm_data,
|
|
cmd_addr => cmd_addr,
|
|
cmd_data => cmd_data,
|
|
cmd_we => cmd_we,
|
|
tx_pcm_addr => tx_pcm_addr,
|
|
tx_pcm_data => tx_pcm_data,
|
|
tx_pcm_we => tx_pcm_we,
|
|
ac_sdata_in => ac97_sdata_in,
|
|
ac_bit_clk => ac97_bit_clk,
|
|
ac_reset_n => ac_reset_n,
|
|
ac_sdata_out => ac97_sdata_out,
|
|
ac_ssync => ac_ssync
|
|
);
|
|
|
|
inst_syn_nco: syn_nco
|
|
PORT MAP(
|
|
rst => rst,
|
|
clk => clk,
|
|
pacc_clr => nco_pacc_clr,
|
|
pacc_inc => nco_pacc_inc,
|
|
freq_in => nco_freq_in,
|
|
freq_load => nco_freq_load,
|
|
phase_in => nco_phase_in,
|
|
phase_load => nco_phase_load,
|
|
phase_out => nco_phase_out,
|
|
wave_out_i => pcm_nco_data(left),
|
|
wave_out_q => pcm_nco_data(right),
|
|
out_valid => nco_out_valid
|
|
);
|
|
|
|
inst_cpu_embedded: cpu_embedded
|
|
PORT MAP(
|
|
rst => rst,
|
|
clk => clk,
|
|
ce => cpu_ce,
|
|
int_in => cpu_int_in,
|
|
int_ack => cpu_int_ack,
|
|
xmem_we => cpu_we,
|
|
xmem_re => cpu_re,
|
|
xmem_din => cpu_din,
|
|
xmem_dout => cpu_dout,
|
|
xmem_addr => cpu_addr,
|
|
io_sel => cpu_io_sel
|
|
);
|
|
|
|
inst_xrom: xrom
|
|
PORT MAP(
|
|
clk => clk,
|
|
ce => cpu_ce,
|
|
addr => cpu_addr,
|
|
dout => xrom_data
|
|
);
|
|
|
|
inst_syn_fir_bandpass: syn_fir_bandpass
|
|
PORT MAP(
|
|
rst => rst,
|
|
clk => clk,
|
|
ready_i => fir_bp_ready(left),
|
|
x_valid_i => fir_bp_din_we(left),
|
|
x_din_i => fir_bp_din(left),
|
|
y_valid_i => fir_bp_dout_valid(left),
|
|
y_dout_i => fir_bp_dout(left),
|
|
ready_q => fir_bp_ready(right),
|
|
x_valid_q => fir_bp_din_we(right),
|
|
x_din_q => fir_bp_din(right),
|
|
y_valid_q => fir_bp_dout_valid(right),
|
|
y_dout_q => fir_bp_dout(right)
|
|
);
|
|
|
|
inst_syn_fir_lowpass: syn_fir_lowpass
|
|
PORT MAP(
|
|
rst => rst,
|
|
clk => clk,
|
|
ready_i => fir_lp_ready(left),
|
|
x_valid_i => fir_lp_din_we(left),
|
|
x_din_i => fir_lp_din(left),
|
|
y_valid_i => fir_lp_dout_valid(left),
|
|
y_dout_i => fir_lp_dout(left),
|
|
ready_q => fir_lp_ready(right),
|
|
x_valid_q => fir_lp_din_we(right),
|
|
x_din_q => fir_lp_din(right),
|
|
y_valid_q => fir_lp_dout_valid(right),
|
|
y_dout_q => fir_lp_dout(right)
|
|
);
|
|
|
|
inst_mix_cpx: mix_cpx
|
|
GENERIC MAP
|
|
(
|
|
nbits_in => mix_nbits,
|
|
nbits_in_frac => mix_nbits,
|
|
nbits_out => mix_nbits,
|
|
nbits_out_frac => mix_nbits,
|
|
nbits_scale_z => mix_nbits_scale_z,
|
|
has_in_reg => true,
|
|
has_pipe_reg => true,
|
|
has_out_reg => true,
|
|
rounding => false,
|
|
saturating => false
|
|
)
|
|
PORT MAP
|
|
(
|
|
srst => rst,
|
|
clk => clk,
|
|
in_valid => mix_in_valid,
|
|
x_re_in => mix_x_re,
|
|
x_im_in => mix_x_im,
|
|
y_re_in => mix_y_re,
|
|
y_im_in => mix_y_im,
|
|
out_valid => mix_out_valid,
|
|
z_re_out => mix_z_re,
|
|
z_im_out => mix_z_im
|
|
);
|
|
|
|
inst_lcd_port: lcd_port
|
|
PORT MAP(
|
|
rst => rst,
|
|
clk => clk,
|
|
we => cpu_lcd_we,
|
|
din => cpu_lcd_out_reg,
|
|
dout => cpu_lcd_in_reg,
|
|
lcd_d => sys_lcd_d,
|
|
lcd_e => sys_lcd_e,
|
|
lcd_rs => sys_lcd_rs,
|
|
lcd_rw => sys_lcd_rw
|
|
);
|
|
|
|
------------------------------------------------------------------
|
|
STARTUP_VIRTEX4_inst : STARTUP_VIRTEX4
|
|
port map (
|
|
EOS => started_up, -- End of Startup 1-bit output
|
|
CLK => open, -- Clock input for start-up sequence
|
|
GSR => '0', -- Global Set/Reset input (GSR cannot be used for the port name)
|
|
GTS => '0', -- Global 3-state input (GTS cannot be used for the port name)
|
|
USRCCLKO => '0', -- USRCCLKO 1-bit input
|
|
USRCCLKTS => '0', -- USRCCLKTS 1-bit input
|
|
USRDONEO => '0', -- USRDONEO 1-bit input
|
|
USRDONETS => '0' -- USRDONETS 1-bit input
|
|
);
|
|
|
|
------------------------------------------------------------------
|
|
|
|
end Behavioral;
|
|
|