I am building an audio processor with effects in my final year project using Spartan 6 and there is a problem i am facing. Since my project guide has left my institute , I am facing a few difficulties of which this is one of them. The following is the code for audio playback . When i use it without the clock divider (On board clock of 4 MHz) process i am able to hear the audio . When i change the ADC Clock (Clock Divider from 4 MHz to 44.1 KHz ) i am unable to hear anything . Why is it so. The test bench shows that the ADC clock is divided to 44.1 KHz but its not giving an on board output.
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 17:19:31 01/03/2016
-- Design Name:
-- Module Name: ADC_DAC_interface - 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.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;
entity ADC_DAC_interface is
Port (
------- FPGA global inputs --------
F_RESET : in STD_LOGIC;
F_CLK_4MHz : in STD_LOGIC;
--------------- ADC interface (AD7938) ------------
F_IL : IN STD_LOGIC_VECTOR (1 downto 0); -- Switches for ADC i/p channel selection
F_ADC_D : inout STD_LOGIC_VECTOR (11 downto 0);
F_ADC_CLK : out STD_LOGIC; -- ADC clock
F_ADC_CS_BAR : out std_logic; --chip select
F_ADC_CONVST_BAR: out std_logic; --conversion start
F_ADC_WR_BAR : out std_logic; --write
F_ADC_RD_BAR : out std_logic; --read
--------------- DAC interface (TLV5619) ------------
F_DAC_D : out STD_LOGIC_VECTOR (11 downto 0);
F_WE_BAR : out STD_LOGIC;--13/2
F_CS1_BAR : out STD_LOGIC;
F_CS2_BAR : out STD_LOGIC;
F_CS3_BAR : out STD_LOGIC;
F_CS4_BAR : out STD_LOGIC
-- chipscope_clk : out STD_LOGIC
);
end ADC_DAC_interface;
architecture Behavioral of ADC_DAC_interface is
type state is (reset_s, write_cr, write_cr2, start_conv, check_count_done, read_data);
signal prsnt_s, next_s : state;
signal control_word : std_logic_vector(11 downto 0);
-- signals to count upto 16 instead of using BUSY pin --
signal count_16 : std_logic_vector(3 downto 0):= "0000";
signal start_count : std_logic:= '0';
signal count_done: std_logic:= '0';
signal reset_counter : std_logic:= '1';
signal Clk_in : std_logic;
signal Clk_mod : std_logic;
signal divide_value : integer;
signal counter,divide : integer := 90;
signal data_out_s: std_logic;
signal CLK : STD_LOGIC;
begin
CLK <= F_CLK_4MHz;
Clk_in <= CLK;
divide_value <= divide;
process(Clk_in)
begin
if( rising_edge(Clk_in) ) then
if(counter < divide/2-1) then
counter <= counter + 1;
Clk_mod <= '0';
elsif(counter < divide-1) then
counter <= counter + 1;
Clk_mod <= '1';
else
Clk_mod <= '0';
counter <= 0;
end if;
end if;
end process;
F_ADC_CLK <= Clk_mod;
-- BUFG_inst : BUFG
-- port map (
-- O => clk, -- Clock buffer output
-- I => F_CLK_4MHz -- Clock buffer input
-- );
--address_s <= channel_switch(1 downto 0);
control_word <= "00010" & F_IL(1) & F_IL(0) & "00001";
-- Count 16 clock cycles (time taken for ADC to convert the sampled input)
process(reset_counter, clk, start_count,f_reset)
begin
if(F_RESET = '1' or reset_counter = '1') then
count_16 <= "0000";
elsif (start_count = '1') then
if(clk'event and clk = '1') then
count_16 <= count_16 + '1';
end if;
end if;
end process;
count_done <= count_16(0) and count_16(1) and count_16(2) and count_16(3);
-------------------------- State Transition -------------------------
process(F_RESET, clk)
begin
if(F_RESET = '1') then
prsnt_s <= reset_s;
elsif(clk'event and clk = '1') then
prsnt_s <= next_s;
end if;
end process;
------------------ Conditions for State change ---------------------
process(F_RESET, prsnt_s, count_done)
begin
case prsnt_s is
when reset_s =>
if F_RESET = '1' then
next_s <= reset_s; -- When reset becomes 0,
else -- change state to write_cr
next_s <= write_cr;
end if;
when write_cr =>
next_s <= write_cr2;
when write_cr2 =>
next_s <= start_conv;
when start_conv =>
next_s <= check_count_done;
when check_count_done =>
if count_done = '0' then
next_s <= check_count_done; -- ADC AD7938 takes 13 cycles to convert a
else -- sampled data. So a 4-bit counter is used here.
next_s <= read_data; -- (Previously, BUSY pin was checked. When busy = 0,
end if; -- change state to read_data)
when read_data =>
next_s <= write_cr;
when others =>
next_s <= reset_s;
end case;
end process;
--------------------- Outputs at each state ---------------------------------
process(prsnt_s, control_word,clk)
begin
case prsnt_s is
when reset_s =>
F_ADC_CS_BAR <= '1';
F_ADC_CONVST_BAR <= '1';
F_ADC_WR_BAR <= '1'; -- RESET State
F_ADC_RD_BAR <= '1';
data_out_s <= '0';
F_CS1_BAR <= '1';
F_CS2_BAR <= '1';
F_CS3_BAR <= '1';
F_CS4_BAR <= '1';
F_WE_BAR <= '0';
start_count <= '0';
reset_counter <= '1';
when write_cr =>
F_ADC_CS_BAR <= '0';
F_ADC_CONVST_BAR <= '1';
F_ADC_WR_BAR <= '0'; -- Write Control Word
F_ADC_RD_BAR <= '1'; -- into Control register of ADC 7938
data_out_s <= '1';
F_CS1_BAR <= '1';
F_CS2_BAR <= '1';
F_CS3_BAR <= '1';
F_CS4_BAR <= '1';
F_WE_BAR <= '0';
start_count <= '0';
reset_counter <= '1';
when write_cr2 =>
F_ADC_CS_BAR <= '0';
F_ADC_CONVST_BAR <= '1';
F_ADC_WR_BAR <= '1'; -- Control Word is latched into ADC 7938
F_ADC_RD_BAR <= '1'; -- at the rising edge of WR-bar signal
data_out_s <= '1';
F_CS1_BAR <= '1';
F_CS2_BAR <= '1';
F_CS3_BAR <= '1';
F_CS4_BAR <= '1';
F_WE_BAR <= '0';
start_count <= '0';
reset_counter <= '1';
when start_conv =>
F_ADC_CS_BAR <= '1';
F_ADC_CONVST_BAR <= '0'; -- Conversion is started.
F_ADC_WR_BAR <= '1'; -- ADC drives BUSY output pin HIGH
F_ADC_RD_BAR <= '1';
data_out_s <= '0';
F_CS1_BAR <= '1';
F_CS2_BAR <= '1';
F_CS3_BAR <= '1';
F_CS4_BAR <= '1';
F_WE_BAR <= '0';
start_count <= '1';
reset_counter <= '0';
when check_count_done =>
F_ADC_CS_BAR <= '1';
F_ADC_CONVST_BAR <= '0'; -- CONVST_BAR pin is driven LOW until
F_ADC_WR_BAR <= '1'; -- ADC-BUSY pin goes LOW
F_ADC_RD_BAR <= '1';
data_out_s <= '0';
F_CS1_BAR <= '1';
F_CS2_BAR <= '1';
F_CS3_BAR <= '1';
F_CS4_BAR <= '1';
F_WE_BAR <= '0';
start_count <= '1';
reset_counter <= '0';
when read_data =>
F_ADC_CS_BAR <= '0'; -- Once ADC-BUSY goes LOW, data is
F_ADC_CONVST_BAR <= '1'; -- read from ADC and applied to DAC
F_ADC_WR_BAR <= '1';
F_ADC_RD_BAR <= '0';
data_out_s <= '0';
F_CS1_BAR <= '0';
F_CS2_BAR <= '0';
F_CS3_BAR <= '0';
F_CS4_BAR <= '0';
F_WE_BAR <= NOT clk;
start_count <= '0';
reset_counter <= '1';
end case;
end process;
------ Controlling bidirectional operation of databus --------
F_ADC_D(11 downto 0) <= control_word when data_out_s = '1' else
(others => 'Z');
F_DAC_D <= F_ADC_D;
--process(F_RESET, clk)
--begin
-- if(F_RESET = '1') then
-- F_DAC_D <= (others=>'0');
-- elsif(clk'event and clk = '1') then
-- F_DAC_D <= F_ADC_D;
-- end if;
--end process;
end Behavioral;