Forum: FPGA, VHDL & Co. CS4344 I²S D/A Wandler


von Daniel K. (daniel_k80)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich möchte mit meinem FPGA den o. g. D/A-Wandler ansteuern 
(http://store.digilentinc.com/pmodi2s-stereo-audio-output/). Dazu habe 
ich mir einen I²S-Transmitter geschrieben, der mit 8,192 MHz getaktet 
wird:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
4
entity I2S_Transmitter is
5
    generic (  
6
        DATA_WIDTH : integer := 32
7
    );
8
    port (
9
        Clock   :   in STD_LOGIC;
10
        Data_In :   in STD_LOGIC_VECTOR(31 downto 0); 
11
        Reset   :   in STD_LOGIC;
12
        LRCLK   :   out STD_LOGIC;
13
        DOUT    :   out STD_LOGIC;
14
        MCLK    :   out STD_LOGIC;
15
        Empty   :   out STD_LOGIC    
16
    );
17
end entity;
18
19
architecture I2S_Transmitter_Arch of I2S_Transmitter is
20
21
    signal InputBuffer  :   std_logic_vector(DATA_WIDTH - 1 downto 0) := (others => '0');
22
    signal Empty_Signal :   std_logic := '1';
23
    
24
    signal DOUT_D1      :   std_logic := '0';
25
    signal WS           :   std_logic := '0';
26
    signal Counter      :   integer := 0;
27
28
begin
29
 
30
LRCLK_Logic:
31
        process (Clock)
32
        begin
33
            if(falling_edge(Clock)) then
34
                if(Reset = '1') then
35
                    Counter <= 0;
36
                    WS <= '1';
37
                else
38
                            
39
                    Counter <= Counter + 1;
40
                    
41
                    if(Counter > (DATA_WIDTH / 2 - 1)) then
42
                        WS <= '1';
43
                    else
44
                        WS <= '0';
45
                    end if;
46
                    
47
                    if(Counter = (DATA_WIDTH - 1)) then
48
                        Counter <= 0;
49
                    end if;
50
                end if; 
51
            end if;
52
        end process;
53
    
54
Load_and_shift_out_Data:
55
        process(Clock)
56
        begin
57
            if(falling_edge(Clock)) then
58
                if(Reset = '1') then
59
                    InputBuffer <= (others => '0');
60
                    Empty_Signal <= '1';
61
                else
62
                    if(Empty_Signal = '1') then
63
                        InputBuffer <= Data_In;
64
                        Empty_Signal <= '0';
65
                    else
66
                        InputBuffer <= InputBuffer((DATA_WIDTH - 2) downto 0) & '0';   
67
                        DOUT_D1 <= InputBuffer(DATA_WIDTH - 1);
68
                    end if;        
69
                    
70
                    if(Counter = (DATA_WIDTH - 1)) then
71
                        Empty_Signal <= '1';
72
                    end if;     
73
                end if;
74
            end if;
75
        end process;
76
77
    MCLK <= Clock;
78
    LRCLK <= WS;
79
    DOUT <= DOUT_D1;
80
    Empty <= Empty_Signal;
81
82
end architecture I2S_Transmitter_Arch;

Das ganze Design habe ich in einer Testbench getestet und es sah (meiner 
Meinung nach) gut aus (siehe Screenshot).

Testbench:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
4
entity I2S_Transmitter_TB is
5
--  Port ( );
6
end I2S_Transmitter_TB;
7
8
architecture I2S_Transmitter_TB_Arch of I2S_Transmitter_TB is
9
10
    signal WS       : std_logic := '0';
11
    signal SCK      : std_logic := '1';
12
    signal Empty    : std_logic := '0';
13
    signal Reset    : std_logic := '0';
14
    signal Data_In  : std_logic_vector(31 downto 0) := (others => '0');
15
    signal SD       : std_logic;
16
    signal MCLK     : std_logic;
17
    
18
    constant clk_period:    Time := 122 ns;
19
    constant ws_period:     Time := 16 * clk_period;
20
21
begin
22
23
DUT:
24
    entity work.i2s_transmitter
25
        port map (
26
            MCLK => MCLK,
27
            LRCLK => WS,
28
            Data_In => Data_In,
29
            Clock => SCK,
30
            DOUT => SD,
31
            Empty => Empty,
32
            Reset => Reset
33
        );
34
CLOCK:
35
36
    process
37
    begin
38
        wait for clk_period/2;
39
        SCK <= not SCK;
40
    end process;
41
42
STIMULUS:
43
44
    process 
45
    begin
46
        Data_In <= x"507B507B";
47
        Reset <= '1';
48
        wait for 10 us;
49
        Reset <= '0';
50
        wait for 10 us;
51
        Data_In <= (others => '0');
52
        wait for 30 ms;
53
        Reset <= '1';
54
        wait for 5 ms;
55
        
56
    end process;
57
58
end I2S_Transmitter_TB_Arch;

An das Modul habe ich nun ein paar selbstgepowerte Boxen angeschlossen 
(irgendwelche billig Boxen...Ultron mini cubes 2.0). Allerdings kommt 
kein Sound aus den Boxen...nur irgendwelches rauschen, welches aber 
unabhängig von den Daten ist die ich zum Chip sende.
Wo kann der Fehler stecken?

Danke für die Hilfe!

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Daniel K. schrieb:
> rauschen, welches aber unabhängig von den Daten ist die ich zum Chip
> sende.
Wie sendest du denn Daten zum Chip?

Daniel K. schrieb:
> Dazu habe ich mir einen I²S-Transmitter geschrieben, der mit 8,192 MHz
> getaktet wird
Wie generierst du diesen Takt?

Daniel K. schrieb:
> Wo kann der Fehler stecken?
Hast du ein Oszilloskop?

BTW: warum schon wieder ein neuer Thread?
Das ist doch noch das alte Thema wie im 
Beitrag "I2S Schieberegister", oder nicht?

: Bearbeitet durch Moderator
von Daniel K. (daniel_k80)


Lesenswert?

Hallo Lothar,

Lothar M. schrieb:
> Daniel K. schrieb:
>> rauschen, welches aber unabhängig von den Daten ist die ich zum Chip
>> sende.
> Wie sendest du denn Daten zum Chip?
>

mein Top-Design schaut so aus:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
4
entity Top is
5
    port (
6
        Clock_In   :   in  STD_LOGIC;
7
        MCLK    :   out STD_LOGIC;
8
        LRCLK   :   out  STD_LOGIC;
9
        DEM     :   out STD_LOGIC;
10
        DOUT    :   out STD_LOGIC
11
        );
12
end Top;
13
14
architecture Top_Arch of Top is
15
16
    signal Clock_Out : std_logic := '0';
17
    signal Empty : std_logic;
18
19
    component Clock is
20
        port (
21
          Clock_In : in STD_LOGIC;
22
          Clock_Out : out STD_LOGIC
23
        );
24
    end component;
25
    
26
    component I2S_Transmitter is
27
        port (
28
            Clock   :   in STD_LOGIC;
29
            Data_In :   in STD_LOGIC_VECTOR(31 downto 0); 
30
            Reset   :   in STD_LOGIC;
31
            LRCLK   :   out STD_LOGIC;
32
            DOUT    :   out STD_LOGIC;
33
            MCLK    :   out STD_LOGIC;
34
            Empty   :   out STD_LOGIC        
35
        );
36
    end component;
37
    
38
begin
39
40
Clocking_Wizard: component Clock port map (
41
                    Clock_In => Clock_In,
42
                    Clock_Out => Clock_Out
43
                    );
44
   
45
I2S:              component I2S_Transmitter port map (
46
                    Clock => Clock_Out,
47
                    MCLK => MCLK,
48
                    LRCLK => LRCLK,
49
                    DOUT => DOUT,
50
                    Data_In => x"77777777",
51
                    Reset => '0',
52
                    Empty => Empty                    
53
                    );
54
    
55
    DEM <= '0';
56
  
57
end Top_Arch;

Ich sende im Prinzip erst einmal nur die selben Daten...da muss dann ja 
ein konstanter Ton bei raus kommen.

> Daniel K. schrieb:
>> Dazu habe ich mir einen I²S-Transmitter geschrieben, der mit 8,192 MHz
>> getaktet wird
> Wie generierst du diesen Takt?
>

Der Takt wird mittels Clocking Wizzard generiert.

> Daniel K. schrieb:
>> Wo kann der Fehler stecken?
> Hast du ein Oszilloskop?
>

Ja, ich muss es wohl mal wieder aus dem Schrank kramen...gleich mal 
morgen machen :)

> BTW: warum schon wieder ein neuer Thread?
> Das ist doch noch das alte Thema wie im
> Beitrag "I2S Schieberegister", oder nicht?

Im Prinzip gehört es dazu. Nur ich weiß nicht wie das hier gehandhabt 
wird. In anderen Foren (Xilinx, Microsoft, etc.) ist es üblich ein neues 
Problem in einen neuen Thread zu packen und in einem Thread nur ein 
explizites Problem zu diskutieren, auch wenn beide Probleme zum selben 
Thema gehören. Daher habe ich einen neuen Thread auf gemacht...

von Georg A. (georga)


Lesenswert?

Da ist das Timing völlig daneben. MCLK und SCLK sind bei sowas 
eigentlich nie identisch. Bei dir wäre der Sampletakt offensichtlich 
8.192MHz/32=256kHz, was ja wohl ziemlicher Quatsch ist. Schau ins 
Datenblatt vom CS4344, da stehen Vorschriften zu den definierten (aka 
benötigten) Verhältnissen von MCLK zu Sampleclock und ebenso WS/LRCK zu 
SCLK.

Edit:
> Ich sende im Prinzip erst einmal nur die selben Daten...da muss dann ja
> ein konstanter Ton bei raus kommen.

Was soll da rauskommen ausser Gleichspannung, die der Wandler 
wegrechnet?

: Bearbeitet durch User
von Mw E. (Firma: fritzler-avr.de) (fritzler)


Angehängte Dateien:

Lesenswert?

Bei der Waveform stimmt absolut garnichts und das Datenblatt haste wohl 
auch nicht gelesen.
Das ist kein I2S sondern irgendwas anderes.

Ersteinmal bekommste mit 8,192MHz keine Standardsamplerate hin, also man 
nehme 12,288MHz für 48kHz Samplerate.
Mit 8,192MHz geht nur: 128kHz, 64kHz, 32kHz
Mit MCLK = SCLK = 8,192MHz geht nur eine Samplerate von 128kHz.

Zudem sind es zu wenig Bits zwischen 2 Flanken von WS (LRCK).
I2S überträgt 2x32 Bits pro LRCK Periode, auch dann wenn du nur 16 Bit 
des 24Bit DACs brauchst.

Guck dir zudem an ab wann das erste Bit des Samples nach der LRCK Flanke 
übertragen werden darf. Als kleiner Tipp: nicht sofort.

Wie oben schon angesagt, imemr dieselben Daten senden ergibt kein Ton...
Nen Sägezahn (Counter) senden reicht als erster Test.

von Weltbester FPGA-Pongo (Gast)


Lesenswert?

Mw E. schrieb:
> nehme 12,288MHz für 48kHz Samplerate.

Das sind auch die Frequenzen, die ich kenne. Soweit ich mich erinnere, 
liefert die auch der Wandler. Das müsste also irgendwie im Modell der 
Testbench auftauchen.

von Carl D. (jcw2)


Lesenswert?

> Zudem sind es zu wenig Bits zwischen 2 Flanken von WS (LRCK).
> I2S überträgt 2x32 Bits pro LRCK Periode, auch dann wenn du nur 16 Bit
> des 24Bit DACs brauchst.

Kann bis zu 64Bit je Frame übertragen, muß aber nicht. Die 
Philips-Original-Spezifikation nennt an keiner einzigen Stelle eine Zahl 
für die Wortlänge.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Carl D. schrieb:
> Kann bis zu 64Bit je Frame übertragen, muß aber nicht. Die
> Philips-Original-Spezifikation nennt an keiner einzigen Stelle eine Zahl
> für die Wortlänge.

Aber so ziemlich alle DAC Datenblätter wollen da 32Bit sehen bei der 
Config des TE.
Sonst würden die Verhältnisse MCLK/SCLK/LRCK nicht mehr stimmen.

: Bearbeitet durch User
von Weltbester FPGA-Pongo (Gast)


Lesenswert?

Mw E. schrieb:
> Aber so ziemlich alle DAC Datenblätter wollen da 32Bit sehen bei der
> Config des TE.
> Sonst würden die Verhältnisse MCLK/SCLK/LRCK nicht mehr stimmen.

Dafür sind die Takte aber sicher da, daß man das individuell steuern 
kann, oder?

Was den DAC angeht, müsste man das eigentlich belibnig tunen können, 
zumindest bei Aufrechterhalt der Verhältnisse und umtakten.

von Georg A. (georga)


Lesenswert?

Vom MCLK leitet sich alles ab. Und mal abgesehen von den analogen 
Filtern am Ausgang (deren Einfluss man kaum hört, paar dB SNR hin oder 
her) ist es dem DAC ziemlich egal, was die tatsächliche Samplerate ist. 
Im CS4344-Datenblatt stehen auch nur untere und obere Grenzen. Wenn nur 
8.192kHz da sind, werden es halt 32kHz. Gab's ja bei DAT-Longplay auch, 
ist also nicht so ungewöhnlich.

von Daniel K. (daniel_k80)


Lesenswert?

Hallo zusammen,

danke für den ganzen Input. Anscheinend habe ich da was gewaltig 
missverstanden...
Nun gut, ich habe mir mal die ganzen Hinweise durchgelesen und einen 
weiteren Versuch gestartet :)
MCLK nehme ich nun einen Takt von 12,288 MHz. Wegen dem konstanten Pegel 
an DEM/SCLK wechselt der Chip in den internal serial Clock Modus und bei 
2x32 Bit Daten entspricht das dann einer Samplerate von 128 kHz(?).
Das Design habe ich zudem auch angepasst:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
4
entity I2S_Transmitter is
5
    generic (  
6
        DATA_WIDTH_PER_CHANNEL : integer := 32
7
    );
8
    port (
9
        Clock   :   in STD_LOGIC;
10
        Data_In :   in STD_LOGIC_VECTOR(((DATA_WIDTH_PER_CHANNEL * 2) - 1) downto 0); 
11
        Reset   :   in STD_LOGIC;
12
        LRCLK   :   out STD_LOGIC;
13
        DOUT    :   out STD_LOGIC;
14
        MCLK    :   out STD_LOGIC;
15
        Busy   :   out STD_LOGIC    
16
    );
17
end entity;
18
19
architecture I2S_Transmitter_Arch of I2S_Transmitter is
20
21
    signal Data_Left    :   std_logic_vector(((DATA_WIDTH_PER_CHANNEL) - 1) downto 0) := (others => '0');
22
    signal Data_Right   :   std_logic_vector(((DATA_WIDTH_PER_CHANNEL) - 1) downto 0) := (others => '0');
23
    signal Busy_Signal  :   std_logic := '1';
24
    
25
    signal DOUT_D1      :   std_logic := '0';
26
    signal WS           :   std_logic := '0';
27
    signal Counter      :   integer := 0;
28
29
begin
30
 
31
LRCLK_Logic:
32
        process (Clock)
33
        begin
34
            if(falling_edge(Clock)) then
35
                if(Reset = '1') then
36
                    Counter <= 0;
37
                else
38
                            
39
                    Counter <= Counter + 1;
40
                    
41
                    if(Counter = (DATA_WIDTH_PER_CHANNEL - 1)) then
42
                        WS <= '1';
43
                    end if;
44
                    
45
                    if(Counter = ((DATA_WIDTH_PER_CHANNEL * 2)) - 1) then
46
                        Counter <= 0;
47
                        WS <= '0';
48
                    end if;
49
                end if; 
50
            end if;
51
        end process;
52
    
53
Load_and_shift_out_Data:
54
        process(Clock)
55
        begin
56
            if(falling_edge(Clock)) then
57
                if(Reset = '1') then
58
                    Data_Left <= (others => '0');
59
                    Data_Right <= (others => '0');
60
                else
61
                    if(WS = '1') then
62
                        Data_Right <= Data_Right((DATA_WIDTH_PER_CHANNEL - 2) downto 0) & '0';  
63
                        DOUT_D1 <= Data_Right(DATA_WIDTH_PER_CHANNEL - 1);
64
                    else
65
                        Data_Left <= Data_Left((DATA_WIDTH_PER_CHANNEL - 2) downto 0) & '0';  
66
                        DOUT_D1 <= Data_Left(DATA_WIDTH_PER_CHANNEL - 1);
67
                    end if;   
68
                    
69
                    if(Counter = ((DATA_WIDTH_PER_CHANNEL * 2)) - 1) then
70
                        Data_Left <= Data_In(((DATA_WIDTH_PER_CHANNEL * 2) - 1) downto DATA_WIDTH_PER_CHANNEL);
71
                        Data_Right <= Data_In((DATA_WIDTH_PER_CHANNEL - 1) downto 0);
72
                    end if;            
73
                end if;
74
            end if;
75
        end process;
76
77
    MCLK <= Clock;
78
    LRCLK <= WS;
79
    DOUT <= DOUT_D1;
80
    Busy <= Busy_Signal;
81
82
end architecture I2S_Transmitter_Arch;

Und dazu die passende Testbench:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
4
entity I2S_Transmitter_TB is
5
--  Port ( );
6
end I2S_Transmitter_TB;
7
8
architecture I2S_Transmitter_TB_Arch of I2S_Transmitter_TB is
9
10
    signal Clock : std_logic := '0';
11
12
    signal Busy    : std_logic := '0';
13
    signal Reset    : std_logic := '0';
14
    signal LRCLK    : std_logic;
15
    signal Data_In  : std_logic_vector(63 downto 0) := (others => '0');
16
    signal DOUT     : std_logic;
17
    signal MCLK     : std_logic;
18
    
19
    -- 8,192 MHz
20
    -- 128 kHz Abtastfrequenz
21
    constant CLK_Period:    Time := 122.0703 ns;
22
    
23
    component I2S_Transmitter is
24
        port (
25
            Clock   :   in STD_LOGIC;
26
            Data_In :   in STD_LOGIC_VECTOR(63 downto 0); 
27
            Reset   :   in STD_LOGIC;
28
            LRCLK   :   out STD_LOGIC;
29
            DOUT    :   out STD_LOGIC;
30
            MCLK    :   out STD_LOGIC;
31
            Busy    :   out STD_LOGIC    
32
        );
33
    end component I2S_Transmitter;
34
    
35
begin
36
37
I2S_TRANSMITTER_DUT:
38
39
    component I2S_Transmitter port map (
40
                    Clock => Clock,
41
                    Data_In => Data_In,
42
                    Reset => Reset,
43
                    LRCLK => LRCLK,
44
                    DOUT => DOUT,
45
                    MCLK => MCLK,
46
                    Busy => Busy
47
                    );
48
                            
49
Clock_Generation:
50
51
    process
52
    begin
53
        wait for CLK_Period / 2;
54
        Clock <= not Clock;
55
    end process;
56
57
STIMULUS:
58
59
    process 
60
    begin
61
        Data_In <= x"AA000000AA000000";
62
        Reset <= '1';
63
        wait for 10 us;
64
        Reset <= '0';
65
        wait for 10 us;
66
        Data_In <= (others => '0');
67
        wait for 30 ms;
68
        Reset <= '1';
69
        wait for 5 ms;
70
        
71
    end process;
72
73
end I2S_Transmitter_TB_Arch;

Da ist noch ein bisschen Optimierungsbedarf an dem Sender, aber die I²S 
Datenübertragung sollte jetzt dem Standard entsprechen (oder?).

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Mach doch mal besser wieder nen Waveform Bild und sende dabei nur 1en 
als Nutzdaten, damit man sieht wo das startet und aufhöhrt.

von Georg A. (georga)


Lesenswert?

Und wo kommt jetzt SCK her?

von Daniel K. (daniel_k80)


Angehängte Dateien:

Lesenswert?

Anbei habe ich mal den Screenshot von der Simulation angehängt.
SCLK wird bei mir auf einen konstanten Pegel (Low) gezogen (ist in der 
Simulation und im I2S-Sender nicht enthalten, sondern im Top-Design).

von Georg A. (georga)


Lesenswert?

> SCLK wird bei mir auf einen konstanten Pegel (Low) gezogen

Und das hilft was? Dass der Chip intern ein SCK generiert, dass du nicht 
sehen kannst und daher nicht weisst, ob deine Annahmen MCLK/LRCK bzw. 
MCLK/SCLK_int und damit das Timing der Datenausgabe stimmen? So kann man 
sich das Leben auch schwer machen, obwohl man es sich extra leicht 
machen will...

Die Deemphasis brauchst du vermutlich eh nicht...

Erzeuge ALLE Signale selbst, dann ist es viel einfacher, das Timing zu 
checken. SCLK brauchst du intern ja auch, sonst bekommst du deine Daten 
nicht raus, spart also nicht mal was...

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Das sieht jetzt schon mehr nach nem I2S aus, das sollte der DAC 
verstehen.
SCK sollteste auch wieder ausgeben und nich den DAC irgendwas 
interpretieren lassen.

Und wie schon öfter gesagt: nur gleiche Daten senden ergibt kein Ton.

von Burkhard K. (buks)


Lesenswert?

Daniel K. schrieb:
> Anbei habe ich mal den Screenshot von der Simulation angehängt.
> SCLK wird bei mir auf einen konstanten Pegel (Low) gezogen (ist in der
> Simulation und im I2S-Sender nicht enthalten, sondern im Top-Design).

Hallo Daniel,

ich hab den CS4344 / Pmod-I2S mit mehreren, einstellbaren SRates in 
Betrieb. Ein paar grundsätzliche Bemerkungen:

  * Leistunganpassung Codec <--> Boxen?  Laut Datenblatt beträgt die 
minimale Ausgangsimpedanz 100 Ohm - evtl. erstmal nur Kopfhörer 
einstöpseln?

  * Verhältnis MCLK/LRCK - wie bereits gesagt - Datenblattstudium ist 
angesagt. Ein Verhältnis 64:1 ist nur für SR >= 100 kHz spezifiziert 
(Seite 9). Für ein paar Beispiele s.u.

  * Roll your own Testsignal - z.B. 100 16bit Sinus-Werte in einem ROM 
ablegen - gibt bei 200kHz SR einen 2kHz Ton . Siehe Code-Beispiel unten.

  * Ohne Logic-Analyzer (oder wenigstens Oszi) wirst Du bei der 
Fehlersuche nicht weit kommen. Lege MCLK/SCLK/LRCK als Debug-Signale auf 
einen freien PMOD-Port. Evtl. noch das MSB des Datenwortes, dann siehst 
Du noch gleich den Wechsel vom positiven zum negativen Wertebereich.

Gruß,
Burkhard

1
-- Expected Inputs:
2
--    clk         : MCLK precursor := 2x MCLKmax
3
--   l_data/r_data  : PCM 16 bit 2'complement audio data
4
--   sr_sel      : Sample rate selection (MCLK:LRCK:SCLK)
5
--                "0000"  QSM (e.g. 192 kHz / 128:1:32)
6
--                "0001"   DSM (e.g.  96 kHz / 256:1:32)
7
--                "001x"  SSM (e.g.  48 kHz / 256:1:32)
8
--                "01xx"  SSM (e.g.  32 kHz / 256:1:32)
9
--                "1xxx"  SSM (e.g.  24 kHz / 256:1:32)
10
--                for standard sample rates use CLK generator (CLK_IN1) at 49.576 MHz
11
--    dmph_n      : '1' to generate SCLK, '0' to suppress external SCLK generation
12
--                     (CS4344: enable Deemphasis)
13
14
15
  constant C_ROM_WIDTH: integer := 100;
16
  signal rindex: integer range 0 to C_ROM_WIDTH-1;
17
  type romdata_t is array (0 to C_ROM_WIDTH-1) of std_logic_vector(15 downto 0);
18
  constant sinus: romdata_t := (
19
    x"0000",  x"0805",  x"1002",  x"17ee",  x"1fc3",
20
    x"2777",  x"2f04",  x"3662",  x"3d89",  x"4472",
21
    x"4b16",  x"516f",  x"5776",  x"5d25",  x"6276",
22
    x"6764",  x"6bea",  x"7004",  x"73ad",  x"76e1",
23
24
    x"799e",  x"7be1",  x"7da7",  x"7eef",  x"7fb7",
25
    x"7fff",  x"7fc6", x"7f0c",  x"7dd3",  x"7c1b",
26
    x"79e6",  x"7737",  x"7410",  x"7074",  x"6c67",
27
    x"67ed",  x"630a",  x"5dc4",  x"5820",  x"5222",
28
29
    x"4bd3",  x"4537",  x"3e55",  x"3735",  x"2fdd",
30
    x"2855",  x"20a5",  x"18d3",  x"10e9",  x"08ee",
31
    x"00e9",  x"f8e4",  x"f0e6",  x"e8f7",  x"e120",
32
    x"d967",  x"d1d5",  x"ca72",  x"c344",  x"bc54",
33
    
34
    x"b5a7",  x"af46",  x"a935",  x"a37c",  x"9e20",
35
    x"9926",  x"9494",  x"906e",  x"8cb8",  x"8976",
36
    x"86ab",  x"845a",  x"8286",  x"8130",  x"8059",
37
    x"8003",  x"802d",  x"80d8", x"8203",  x"83ad",
38
39
    x"85d3",  x"8875",  x"8b8f",  x"8f1d",  x"931e",
40
    x"978c",  x"9c63",  x"a19e",  x"a738",  x"ad2b",
41
    x"b372",  x"ba05",  x"c0df",  x"c7f9",  x"cf4b",
42
    x"d6ce",  x"de7a",  x"e648",  x"ee30",  x"f629"
43
  );

von Daniel K. (daniel_k80)


Lesenswert?

Burkhard K. schrieb:
> Daniel K. schrieb:
>
> Hallo Daniel,
>
> ich hab den CS4344 / Pmod-I2S mit mehreren, einstellbaren SRates in
> Betrieb. Ein paar grundsätzliche Bemerkungen:
>
>   * Leistunganpassung Codec <--> Boxen?  Laut Datenblatt beträgt die
> minimale Ausgangsimpedanz 100 Ohm - evtl. erstmal nur Kopfhörer
> einstöpseln?
>
>   * Verhältnis MCLK/LRCK - wie bereits gesagt - Datenblattstudium ist
> angesagt. Ein Verhältnis 64:1 ist nur für SR >= 100 kHz spezifiziert
> (Seite 9). Für ein paar Beispiele s.u.
>
>   * Roll your own Testsignal - z.B. 100 16bit Sinus-Werte in einem ROM
> ablegen - gibt bei 200kHz SR einen 2kHz Ton . Siehe Code-Beispiel unten.
>
>   * Ohne Logic-Analyzer (oder wenigstens Oszi) wirst Du bei der
> Fehlersuche nicht weit kommen. Lege MCLK/SCLK/LRCK als Debug-Signale auf
> einen freien PMOD-Port. Evtl. noch das MSB des Datenwortes, dann siehst
> Du noch gleich den Wechsel vom positiven zum negativen Wertebereich.
>
> Gruß,
> Burkhard

Hallo Burkhard,

danke für den Hinweis. Ich habe mich gestern noch einmal dran gesetzt 
und den kompletten Code überarbeitet. Dabei habe ich jetzt auch MCLK und 
SCLK vom FPGA erzeugt und mir die einzelnen Takte etwas genauer 
angeschaut.
Ich bekomme jetzt auch einen Ton raus etc., sprich der Transmitter und 
die Ansteuerung funktionieren :)

von Daniel K. (daniel_k80)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

um den Thread hier mal abzuschließen poste ich mal meine Lösung (falls 
jemand was ähnliches benötigt etc. ).
Ich habe mir zusätzlich noch ein kleines Programm in C# geschrieben um 
eine Wave-Datei auszulesen und die Daten in ein .coe-File für den Xilinx 
Block Memory Generator zu schreiben (siehe Anhang).
Als Testfile habe ich mir ein Wave-File mit 16-Bit Auflösung, 1 Kanal 
und 48 KHz Samplerate heruntergeladen:

(http://download.wavetlan.com/SVV/Media/HTTP/http-wav.htm)

Die VHDL-Sourcen hänge ich ebenfalls mal an. Alles was dann noch 
benötigt wird ist ein Blockdesign mit einem ROM und eine Taktquelle die 
12,288 MHz erzeugt.

Noch mal an alle ein Dankeschön für die Hilfe :)

: Bearbeitet durch User
von Wupps (Gast)


Lesenswert?

Daniel K. schrieb:
> Die VHDL-Sourcen hänge ich ebenfalls mal an. Alles was dann noch
> benötigt wird ist ein Blockdesign mit einem ROM und eine Taktquelle die
> 12,288 MHz erzeugt.


 Warning: (vsim-3473) Component instance "Sinewave_ROM : Audio_ROM" is 
not bound.

von Daniel K. (daniel_k80)


Angehängte Dateien:

Lesenswert?

Wupps schrieb:
> Daniel K. schrieb:
>> Die VHDL-Sourcen hänge ich ebenfalls mal an. Alles was dann noch
>> benötigt wird ist ein Blockdesign mit einem ROM und eine Taktquelle die
>> 12,288 MHz erzeugt.
>
>
>  Warning: (vsim-3473) Component instance "Sinewave_ROM : Audio_ROM" is
> not bound.

Hallo Wupps,

bei dem Audio_ROM handelt es sich um ein Blockdesign, welches mit dem 
.coe-File initialisiert wird (siehe Anhang).

von J. S. (engineer) Benutzerseite


Lesenswert?

Das RAM/ROM und die PLL kann man auch als Primitive direkt hinschreiben 
- oder aus dem ->Library Guide rauskopieren.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.