Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Audio Processor Using FPGA

Status
Not open for further replies.

mlpin94

Newbie level 4
Joined
Apr 7, 2015
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
88
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.
----------------------------------------------------------------------------------
Code:
-- 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;
 
Last edited by a moderator:

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.
Suggests you start reading the ADC datasheet. It's quite obvious that the ADC clock input must be a multiple of the intended conversion rate.

Also the timing of the busy output depends on the master clock. It's likely that busy didn't ever reach high state when your state machine detects and of conversion...
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top