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
endif;
12
endif;
13
endif;
14
endprocess;
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(14downto0)&'0';
25
endif;
26
endif;
27
endif;
28
endprocess;
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!
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.
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?
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
@ 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.
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...
@ 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ö.
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".
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...
Eine eigene Frage?
Dieser Thread ist über 10 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.