Forum: FPGA, VHDL & Co. I2S Schieberegister


von Daniel K. (daniel_k80)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich baue mir gerade einen I2S-Master zusammen und habe folgenden Code:
1
 Load_Data:
2
        process(SCK)
3
        begin
4
            if(falling_edge(SCK)) then
5
                if(Reset = '1') then
6
                    InputBuffer <= (others => '0');
7
                else
8
                    if(Empty_Signal = '1') then
9
                        InputBuffer <= Data_In;
10
                        Empty_Signal <= '0';
11
                    end if;             
12
                end if;
13
            end if;
14
        end process;
15
        
16
    Shift_out_Data:
17
        process(SCK)
18
        begin
19
            if(falling_edge(SCK)) then
20
                if(Reset = '1') then
21
                    --SD <= '0';
22
                else
23
                    if(Empty_Signal = '0') then
24
                        InputBuffer <= InputBuffer(14 downto 0) & '0';
25
                    end if;
26
                end if;
27
            end if;
28
        end process;

Die Idee dahinter ist folgende:
Ich lege Daten an meinen I2S-Master, der liest diese ein und gibt ein 
entsprechendes Signal nach außen weiter, sodass dann neue Daten angelegt 
werden können. Sobald die Daten eingelesen wurden, soll das raus shiften 
der Daten beginnen.
Die Simulation spuckt nun aber einen Fehler aus (siehe Screenshot).
Woher kommt der Fehler? Beim ersten Taktsignal ist "Empty_Signal" doch 
1, wodurch er die Daten in den Buffer lädt und dann "Empty_Signal" auf 0 
setzt.
Und erst beim zweiten Takt arbeitet er die Bedingung ab, wo die Daten 
geshiftet werden. Wo ist mein Denkfehler?

Danke für die Hilfe!

von Klakx (Gast)


Lesenswert?

du hast zwei Prozesse die auf InputBuffer schreiben. Dadurch bekommst du 
X. Du solltest nur einen Prozess für dieses Signal haben um kein 'X' zu 
bekommen.

von Daniel K. (daniel_k80)


Lesenswert?

mmh ok. Aber die Prozesse schreiben doch nicht gleichzeitig auf 
"InputBuffer". Oder ist das ein grundsätzliches Problem, wenn ich zwei 
Prozesse habe die einen Wert ändern wollen?

von Falk B. (falk)


Lesenswert?

Das ist das Problem! Für so ein triviales Schieberegister braucht man 
nicht 2 Prozesse, das geht locker und deutlich übersichlicher in einem.

: Bearbeitet durch User
von Burkhard K. (buks)


Lesenswert?

Daniel K. schrieb:
> mmh ok. Aber die Prozesse schreiben doch nicht gleichzeitig auf
> "InputBuffer".

Aber klar tun sie das. Du beschreibst hier eine Schaltung (kein 
Programm), die beiden Prozesse sind "concurrent".

Darüberhinaus handelst Du Dir mit der einseitigen Auswahl (fehlender 
Else-Zweig) ein weiteres Problem ein: die Synthese würde daraus ein 
"Latch" (level-sensitiv) generieren. Das hat in einem synchronen Design 
nichts zu suchen. Wer "if" schreibt, muss auch "else" sagen!


Gruß,
Burkhard

von Falk B. (falk)


Lesenswert?

@ Burkhard K. (buks)

>Darüberhinaus handelst Du Dir mit der einseitigen Auswahl (fehlender
>Else-Zweig) ein weiteres Problem ein: die Synthese würde daraus ein
>"Latch" (level-sensitiv) generieren. Das hat in einem synchronen Design
>nichts zu suchen. Wer "if" schreibt, muss auch "else" sagen!

Nö. Das gilt nur für kombinatorische Prozesse. Bei getakteten ist das 
unkritisch, das werden so oder so FlipFlops.

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


Lesenswert?

Mal abgesehen, dass schon formal einem Signal nicht aus 2 Prozessen 
zugewiesen werden darf, liegt das Problem in der Denkweise:
Daniel K. schrieb:
1
        if(falling_edge(SCK)) then ...
2
             InputBuffer <= ...;
3
4
        ...
5
6
        if(falling_edge(SCK)) then
7
             InputBuffer <= ...;
Eine Beschreibung, die ein "xxx_edge()" abfragt, ergibt im FPGA immer 
ein Flipflop. So ist der "InputBuffer" einfach ein Haufen Flipflops.
Und deshalb wurde hier ein Flipflop beschrieben, das auf jede Taktflanke 
(steigend und fallend) reagiert. Solche Flipflops gibt es aber nicht 
(oder bestenfalls als Pseudo DDR-Flipflops bei den IO-Zellen).
Ergo kann der Synthesizer diese Beschreibung nicht in Hardware 
umsetzen...

: Bearbeitet durch Moderator
von Falk B. (falk)


Lesenswert?

@ Lothar Miller (lkmiller) (Moderator) Benutzerseite

>        if(falling_edge(SCK)) then ...
>             InputBuffer <= ...;

>        if(falling_edge(SCK)) then
>             InputBuffer <= ...;

>Und deshalb wurde hier ein Flipflop beschrieben, das auf jede Taktflanke
>(steigend und fallend) reagiert.

Nö.

von J. S. (engineer) Benutzerseite


Lesenswert?

Soweit ich sehe, wird nur falling_edge benutzt, von daher sollte das 
funktionieren. Das ist aber trotzdem sehr unschön. Ich hatte schon 
mehrere Designs zur Reparatur, in denen der Vorentwickler beide Takte 
benutzt habe und ich bin nicht sicher, was da jeweils gebaut worden war. 
Ein DDR-FlipFlop kann es nur im Ausnahmefall gewesen sein, weil es das 
physikalisch inmitten des FPGAs ja nicht gibt. Gfs drängt die Synthese 
sowas auch mal an den Rand und baut was.

Ich errinnere mich, dass ich seinerzeit mal probiert habe, solche 
Konstrukte systematisch zu erforschen, aber das Einzige, was ich 
verbindlich sagen kann, ist, daß man da nichts verlässliches sagen kann.

Daher mein Ratschlag: "Finger weg vom falling_edge".

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


Lesenswert?

Falk B. schrieb:
> Nö.
Jürgen S. schrieb:
> Soweit ich sehe, wird nur falling_edge benutzt
Korrekt. Schlimm, sowas... :-/

Jürgen S. schrieb:
> Soweit ich sehe, wird nur falling_edge benutzt, von daher sollte das
> funktionieren.
Dann verbleibt also das rein syntaktische Problem, dass auf ein Signal 
nur von 1 Prozess getrieben werden darf. Dabei gilt auch, dass 
Concurrent-Beschreibungen auch nur abgekürzte Prozesse sind...

: Bearbeitet durch Moderator
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.