I2S Schieberegister

OP #4574533
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!
Angehängte Dateien:
#4577636
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
#4577797
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.
Moderator (Firma: Titel) Persönliche Seite #4577961
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...
#4577967
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ö.
Persönliche Seite #4578281
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".
Moderator (Firma: Titel) Persönliche Seite #4578355
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...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren