Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17255 Discussions

Audio Processor Using FPGA SPARTAN 6

Altera_Forum
Honored Contributor II
3,552 Views

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;

0 Kudos
2 Replies
Altera_Forum
Honored Contributor II
2,572 Views

You're not going to find much advice about a xilinx FPGA on the Altera forum. I'd suggest going to http://forums.xilinx.com

0 Kudos
Altera_Forum
Honored Contributor II
2,572 Views

It looks like your problem is the Clock used to generate the ADC signals. 

 

In your example the ADC is clocked with a 44.1 KHz clock whereas the control and data signals are still generated with the 4 MHz clock. 

If you change  

CLK <= F_CLK_4MHz; 

Clk_in <= CLK; 

to 

CLK <= Clk_mod; 

Clk_in <= F_CLK_4MHz; 

it should work.
0 Kudos
Reply