Jump to content
  • 0

Genesys 2 Audio Codec with FIR filter


itse me mario

Question

Hello everybody,

I´m trying to implement a FIR filter with a sampling rate of 16 kHz on the Genesys 2 Board (Vivado 2019.2, VHDL). For that reason I need to configure the onboard Audio-Codec (ADAU1761). I already designed a FIR-filter, that I want to use later. Unfortunately I am quite new to FPGA design and I´m struggling a bit with it.

I found an article „Audio Interface for the Zedboard“ from Stefan Scholl (TU Kaiserslautern Germany, see https://kluedo.ub.uni-kl.de/frontdoor/deliver/index/docId/4034/file/zedboard_audio_doc.pdf), which is based on a framework from Mike Field alias hamster).  Also the VHDL-files are included (see https://github.com/ems-kl/zedboard_audio).

I converted this framework into a Genesys 2 framework, since it is the same Audio Codec. Unfortunately something is not working and I don´t know how to go on right now.

 

At first I want to give the LINE IN input directly to the HP OUT Output. As a next step I want to integrate my previous FIR filter. For evaluation of proper functionality of the FIR filter I´m going to use the Analog Discovery 2 (analyzing the transfer function with sinus sweeps).

My next steps:

  1.  I wanted to use the ILA (Integrated Logic Analyzer) for the signal values. Unfortunately I have some problems when integrating the ILA for line_in_ and hphone_out_ signals (Error: OBUFT [DRC REQP-1581] obuf loaded: OBUFT_i i_audio/…/OBUFT_inst pin O drives one or more invalid loads. The loads are: i_audio/…/i2c_data[0]_i_1
  2. Moreover I wanted to use the AD2 as logic analyzer and therfore route the signals on some pins (I´m waiting for bread board cables).

 

Furthermore when generating the bitsteam I get critical warnings:

[Timing 38-282] The design failed to meet the timing requirements. Please see the timing summary report for details on the timing violations.

[Board 49-67] The board_part definition was not found for digilentinc.com:genesys2:part0:1.1. This can happen sometimes when you use custom board part. You can resolve this issue by setting 'board.repoPaths' parameter, pointing to the location of custom board files. Valid board_part values can be retrieved with the 'get_board_parts' Tcl command.

 

I first thought my framework is working but when setting hphone_out_l and hphone_out_r to 0, I still hear the music from my IPod (because of the default startup program).

When finished, I want to upload the Audio Codec Interface. Maybe someone else also needs the interface.

 

If someone can help me or has another Audio Codec design for the Genesys 2 (that he is willing to share), I would be very pleased!

I added an Overview of the modules, a block design for all modules, the previous codec configuration (docx) and the code modules. If desired I can upload additional  files.

 

I´m looking forward to hearing from you.

Thanks a lot and stay healthy,

Mario

Registersettings.docx OverviewAndModules_new.pdf Genesys2Master.xdc adau1761_configuraiton_data.vhd ADAU1761_interface.vhd ADAU1761_izedboard.vhd audio_testbench.vhd audio_top.vhd clocking.vhd i2c.vhd i2s_data_interface.vhd i3c2.vhd reg_pack.vhd

Link to comment
Share on other sites

18 answers to this question

Recommended Posts

Some updates. Took a while because I tried out a lot.

I set the 48 MHz and 100 MHz clocks from the clocking wizards output to be asynchronous (https://www.xilinx.com/video/hardware/clock-group-constraints.html). Now in the XDC I have: set_clock_groups -asynchronous -group [get_clocks *clk_out1*] -group [get_clocks *clk_out2*]

I also added set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
in the XDC.

Furthermore I added additional board files (https://reference.digilentinc.com/reference/software/vivado/board-files).

 

Unfortunately I still hear music from the IPod when I set hphone_l and hphone_r to 0... This means the default program is running I guess.

 

I think I can ignore the warning "No constraints selected or write" (https://www.xilinx.com/support/answers/73510.html).

 

I attached the remaining warnings (no critical warnings left).

 

I think I try to implement the ILA next. I´m thankful for any hint.

 

Thank you.

 

ErrorsundWarnings_new_new.PNG

Link to comment
Share on other sites

I had an error in an old file (fsm_fir_get_data)... Now DA_SDIN, etc represent the data.

...

begin

calc_next_state: process ( state,start_fs_tic_f )

begin case state is

--************new****************

when s_idle => if (start_fs_tic_f='1') then nxt_state <= s_read; end if;

--******************************

--************old***************

when s_idle =>  if (start_fs_tic_f='1' AND rising_edge(start_fs_tic_f) ) then nxt_state <= s_read; end if;

--*****************************

...

Link to comment
Share on other sites

I´m running out of ideas... Testbench works fine.

Using the analog discovery 2 I can measure the clock signals (MCLK, LRCK, SCLK). AD_SDOUT and DA_SDIN remain 0 (see AD2_neu2.png).

Using the ILA (when AD2 is also connected) all signals remain zero. Without AD2 it shows at least values for audio_l_out and audio_r_out. AD_SDOUT also seems to work.

 

I also tried once with set_property CONFIG_VOLTAGE 5 [current_design] but it did not help.

 

My XDC:

set_clock_groups -asynchronous -group [get_clocks *clk_out1*] -group [get_clocks *clk_out2*]
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]


set_property -dict {PACKAGE_PIN AD11 IOSTANDARD LVDS} [get_ports sysclk_n]
set_property -dict {PACKAGE_PIN AD12 IOSTANDARD LVDS} [get_ports sysclk_p]

 

## PMOD Header JA
set_property -dict {PACKAGE_PIN U28 IOSTANDARD LVCMOS33} [get_ports { DA_LRCK }]; #IO_L13N_T2_MRCC_14 Sch=ja_n[1]
set_property -dict {PACKAGE_PIN U27 IOSTANDARD LVCMOS33} [get_ports { DA_MCLK }]; #IO_L13P_T2_MRCC_14 Sch=ja_p[1]
set_property -dict {PACKAGE_PIN T27 IOSTANDARD LVCMOS33} [get_ports { DA_SDIN }]; #IO_L12N_T1_MRCC_14 Sch=ja_n[2]
set_property -dict {PACKAGE_PIN T26 IOSTANDARD LVCMOS33} [get_ports { DA_SCLK }]; #IO_L12P_T1_MRCC_14 Sch=ja_p[2]

set_property -dict {PACKAGE_PIN T23 IOSTANDARD LVCMOS33} [get_ports { AD_LRCK }]; #IO_L5N_T0_D07_14 Sch=ja_n[3]
set_property -dict {PACKAGE_PIN T22 IOSTANDARD LVCMOS33} [get_ports { AD_MCLK }]; #IO_L5P_T0_D06_14 Sch=ja_p[3]
set_property -dict {PACKAGE_PIN T21 IOSTANDARD LVCMOS33} [get_ports { AD_SDOUT }]; #IO_L4N_T0_D05_14 Sch=ja_n[4]
set_property -dict {PACKAGE_PIN T20 IOSTANDARD LVCMOS33} [get_ports { AD_SCLK }]; #IO_L4P_T0_D04_14 Sch=ja_p[4]

 

top-level module:

entity AudioInterface is
port(
    sysclk_p    : in std_logic;
    sysclk_n    : in std_logic;
    
--*************************used PMOD pins********************************************
    DA_LRCK     : OUT STD_LOGIC;
    DA_MCLK     : OUT STD_LOGIC;
    DA_SDIN     : OUT STD_LOGIC;
    DA_SCLK     : OUT STD_LOGIC;
    
    AD_LRCK     : OUT STD_LOGIC;
    AD_MCLK     : OUT STD_LOGIC;
    AD_SDOUT    : IN STD_LOGIC;
    AD_SCLK     : OUT STD_LOGIC
--************************************************************************************
    );
end AudioInterface;

...

 

    DA_LRCK     <= s_clk_32_kHz_LRCK;
    DA_MCLK     <= s_clk_8_192_MHz_MCLK;
    DA_SCLK     <= s_clk_2_048_MHz_SCLK;
    ------------------------------------
    AD_LRCK     <= s_clk_32_kHz_LRCK;
    AD_MCLK     <= s_clk_8_192_MHz_MCLK;
    AD_SCLK     <= s_clk_2_048_MHz_SCLK;
    

...

 

i2s_interface : i2s_data_interface
    port map (
                   clk           => s_clk_8_192_MHz_MCLK,
                   audio_l_in    => s_audio_l_in,  
                   audio_r_in    => s_audio_r_in,  
                   audio_l_out   => s_audio_l_out,
                   audio_r_out   => s_audio_r_out, 
                   new_sample    => s_new_sample,
                   i2s_bclk      => s_clk_2_048_MHz_SCLK,
                   i2s_d_out     => DA_SDIN, 
                   i2s_d_in      => AD_SDOUT,
                   i2s_lr        => s_clk_32_kHz_LRCK
             );

...
 

 

 

AD2_neu2.PNG

Link to comment
Share on other sites

Hello together,

as mentioned I bought the PMOD-I2S interface, so I don´t need an I2C master controller anymore.

I changed my design and added my previously designed FIR-Filter (see RTL.png).

I use a MCLK of 8.192 MHz, a LRCK of 32 kHz and a SCLK of 2.048 MHz.

My filter needs 16 bit input data and creates 16 bit output data.

 

Unfortunately in my new design in the beginning every second value in array a_sop (Array of Sum of Products) is  XXXX...XXXX and I don´t know why. I tried different things, but nothing works so far (see WrongValues, WrongValues_zoom, WrongValues2, WrongValues2_zoom). 

Maybe someone has an idea what´s going on there? 

Thank you very much! 

 

RTL.PNG

Correct.PNG

WrongValues.PNG

WrongValues2.PNG

ReportDrivers.PNG

WrongValues2_zoom.PNG

WrongValues_zoom.PNG

AudioInterface.vhd FIRFilter.vhd

Link to comment
Share on other sites

Hello it´s me again.

Another problem occured. When using the ILA, I get a warning (see attachment). When I use an already tested program on the Genesys2, I get the same error message, but the ILA shows the right results and triggers. Could this warning be the reason why it´s not working, or does it not affect the functionality? My ILA clock is directly connected to the output from the clocking wizard. The following link https://www.xilinx.com/support/answers/64764.html hasn´t helped me so far. As trigger signals I used new_sample=1 and the rising edge of sample_clk_48k. Unfortunately the ILA does not trigger automatically. As input signal (Line In) I used my IPod, aswell as the Analog Discovery 2 (sine sweeps).  Oddly enough the signal count has sometimes increased after the first forced trigger, but then stayed constant. This signal is set to 0 by default. 

Code for the ILA:

COMPONENT ila_0 PORT (

clk : IN STD_LOGIC;

probe0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);

probe1 : IN STD_LOGIC_VECTOR(23 DOWNTO 0);

probe2 : IN STD_LOGIC_VECTOR(23 DOWNTO 0);

probe3 : IN STD_LOGIC_VECTOR(23 DOWNTO 0);

probe4 : IN STD_LOGIC_VECTOR(23 DOWNTO 0);

probe5 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);

probe6 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);

probe7 : IN STD_LOGIC_VECTOR(5 downto 0) );

END COMPONENT ;

 

signal sample_clk_48k_vec : STD_LOGIC_VECTOR (0 downto 0):= "0";

signal new_sample_vec : STD_LOGIC_VECTOR (0 downto 0):= "0";

signal hphone_valid_vec : STD_LOGIC_VECTOR (0 downto 0):= "0";

-- keep signals for tracking them with the Logic Analyzer

attribute keep : string;

attribute keep of sample_clk_48k : signal is "true";

attribute keep of hphone_l : signal is "true";

attribute keep of hphone_r : signal is "true";

attribute keep of line_in_l : signal is "true";

attribute keep of line_in_r : signal is "true";

-- newly inserted 

attribute keep of new_sample : signal is "true";

attribute keep of hphone_valid : signal is "true";

attribute keep of counter : signal is "true";

-- newly inserted end

...

sample_clk_48k_vec(0) <= sample_clk_48k;

new_sample_vec(0) <= new_sample;

hphone_valid_vec(0) <= hphone_valid;

ila : ila_0 PORT MAP (

clk => s_clk_100_MHz,

probe0 => sample_clk_48k_vec,

probe1 => line_in_l,

probe2 => line_in_r,

probe3 => hphone_l,

probe4 => hphone_r,

probe5 => new_sample_vec,

probe6 => hphone_valid_vec,

probe7 => std_logic_vector(counter) );

 

Someone got an idea, what I can do? Right now I´m in a dead end. I´m thankful for any help!  I also uploaded an overview of the actual connections.

 

Best regards

Mario

 

neuesDiagramm3.png

dbg_hub.PNG

Debug.PNG

ILA2.PNG

ILA3.PNG

Link to comment
Share on other sites

Hi, 

thanks again for your answer! 

>>break down the problem into smaller pieces 

I think so, too. Otherwise it´s hard to find the errors.

>>BTW, the current consumption of your codec might serve as quick-and-dirty indicator that your register writes are going through (works for a module, not sure if this will help you)..

Alright this might be a good idea, thank you!

 

>>PS: "FPGA" is DSP implementation, [...]

Yes I first developed the algorithm on a DSP and a microcontroller and checked the transfer function. I additionally checked and compared the outputs with a small C program. It´s a fixed-point FIR filter with 16 bit coefficients and input data. Moreover saturation and a 48 bit accumulator are integrated (multiply adder blocks). 

 

 

 

 

Link to comment
Share on other sites

PS: "FPGA" is DSP implementation, usually fixed point, which is a fairly specialized topic. Do not try to use an FPGA to develop or debug at algorithm level, Do the algorithm work elsewhere (Octave/Matlab? Raspberry Pi? PC with e.g. Portaudio and a soundcard? Just about anything else that does not have the letters "FPGA" in it ...)

Link to comment
Share on other sites

2 hours ago, itse me mario said:

Writing a testbench for simulating the audio codec with all necessary signals isn´t easy for sure?

True but you'll need some means to break down the problem into smaller pieces that can be debugged individually. Otherwise you have this big black box and the information "it doesn't work".

I'm not trying to sell you any methodology, simple answers or miracle tools - I would cut most corners myself if I had to do a similar job but you may need a little more "scaffolding" if doing it for the first time. A lot more if learning FPGA design along the way.

BTW, the current consumption of your codec might serve as quick-and-dirty indicator that your register writes are going through (works for a module, not sure if this will help you)..

Link to comment
Share on other sites

Hi,

thank you for your answer. Okay I will try to solve this timing problem first, before I continue.

I already worked on some projects (7 segment decoder, UART with AXI: register reader, FIR filter, ILA in a small project), also with state machines. I have problems with the audio codec, but the framework, especially the state machines for the initialization should actually work. Maybe I added some errors...

 One thing is that I really need a working audio codec for my future projects (FIR filter and adaptive filter next).

 

>>For example, a small state machine that takes registers and values from UART in some hex notation, writes them to the CODEC 

Is this easier than my design? ? The configuration of the codec is also a must, isn´t it? At first a simple talkthrough is all I want.

 

>>A problem with FPGA is that you get very little feedback from the hardware ("it doesn't work"). 

I totally agree with you...

 

Writing a testbench for simulating the audio codec with all necessary signals isn´t easy for sure?

I have 3 books (2x Reichhardt and Meyer-Baese: Digital Signal Processing with FPGAs) but suggestions for useful material would be very great.

Thank you very much.

 

Best regards

Mario

 

Link to comment
Share on other sites

Hi,

this one...

>> The design failed to meet the timing requirements. Please see the timing summary report for details on the timing violations.

... is unfortunately serious. I wouldn't even "try" on hardware, it's a dead end for several reasons (may also cause the tools to run really slowly).
I'd comment out the ILA until this error is understood.

Expect to spend a working week on the issue if you're new to FPGA - you don't just want to shake the box until the error goes away but also understand what actually happened so it doesn't come back.

Opinion: Your large design may be not the most practical platform for this kind of study, I'd start with something smaller. For example, a small state machine that takes registers and values from UART in some hex notation, writes them to the CODEC and reads back for verify. When that works and you need an audio signal, start with a simple counter (=> triangle wave).

A problem with FPGA is that you get very little feedback from the hardware ("it doesn't work"). At this point, most people would take a step back to simulation which isn't really compatible with your plan of debugging with a signal generator... You will probably find out yourself that this strategy is not efficient, it's usually reserved for situations where you have no other choice.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...