Forum: FPGA, VHDL & Co. Prozess Problem, ausgabe FPGA entspricht nicht der Simulation


von fragender (Gast)


Lesenswert?

Hallo erst mal mein coder:
1
STATE: process(SYS_CLK)
2
begin
3
  if SYS_CLK'event and SYS_CLK = '0' then
4
    if M_CS='0' then --cs ist nicht da!
5
      
6
    else --cs aktive es geht los  
7
      S_MCLK_OLD <= M_CLK;
8
      if S_MCLK_OLD /= M_CLK and M_CLK='0' then
9
        M_TMP <= MOSI;
10
        if S_BIT_CNT = 0 then
11
          RX_FINISH <= '1';
12
          S_BIT_CNT <= BIT_LAENGE-1;
13
        else
14
          S_BIT_CNT <= S_BIT_CNT-1;
15
          RX_FINISH <= '0';
16
        end if;
17
      else
18
        
19
      end if;
20
    end if;
21
  end if;
22
end process STATE;

SYS_CLK ist mein Systemclk 150 MHz
M_CLK ist mein SPI CLK 8 MHz vom Master
M_CS das Chipselect von Master.
BIT_LAENGE ist 8.

Ich warte auf eine steigende Flanke  vom SYS_CLK.
Danach warte ich einen Flankenwechsel von Masterclk.
Dann schreibe ich die Daten vom Master auf ein TMP regester.
RX_FINISH dient hier nur als Test und gibt zurück wenn S_BIT_CNT null 
erreicht hat.

Ok nun zu meinem Problem. Das ganze ist mega instabil. Ohne die innere 
if schleife sehe ich an M_TMP die Daten vom Master. Mit der inneren 
schleife wird alles instabil weder RX_FINISH zeigt das ende des zählen 
an und der M_TMP macht nur Schwachsinn.
Wenn ich das Ding Simuliere , sieht alles so aus wie ich es mit gedacht 
habe.

Daher bitte helft mir.

Danke.

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


Lesenswert?

fragender schrieb:
> Ich warte auf eine steigende Flanke  vom SYS_CLK
Das tust nur du. Aber dein FPGA wartet da auf gar nichts, sondern die 
beteiligten Flipflops übernehmen einfach mit der entsprechenden 
Taktflanke ihre Eingangsdaten auf ihre Ausgänge. Die Ursache  des 
Problems ist also einfach: du denkst in Software, wo alles hübsch 
nacheinander passiert.

> Ohne die innere if schleife
Es gibt keine if-Schleifen...

Das eigentliche Problem bei diesem Design ist ein klassischer 
Anfängerfehler: asynchrone Eingänge. Hier gleich 3 davon: der M_CS, der 
M_CLK und auch MOSI. Da passiert dann sowas:
http://www.lothar-miller.de/s9y/categories/35-Einsynchronisieren

: Bearbeitet durch Moderator
von fragender (Gast)


Lesenswert?

Hi danke für deine Antwort. Ich denke auch das ich noch zu nah an der c 
Programmierung bin. Ober das Problem haben sicher viele :) danke für den 
Hinweis du hast natürlich recht das es sich um eine Anweisung und nicht 
um eine Schleife handelt.
Ich versuche mal deine Beschreibung auf mein Problem anzuwenden. Hätte 
zwar nie gedacht das es bei den Frequenzen schon Probleme gibt. Aber wie 
in deinem Artikel beschrieben wird hier das Hauptproblem beim den 
eingang master CLK liegen.

Vielen dank

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


Lesenswert?

fragender schrieb:
> Hätte zwar nie gedacht das es bei den Frequenzen schon Probleme gibt
Für "das Problem" reichen 2 Flipflops, 1 Taktflanke, und 1 Signal. Der 
Takt kann also beliebig langsam sein. Es tritt dann nur nicht "so 
häufig"  auf...

von J. S. (engineer) Benutzerseite


Lesenswert?

Die "Clocks" sind hier nicht so  das Problem, weil sie keine FFs 
erzeugen. Allerdings sollte man sich dennoch lieber von dem "Warten" 
verabschieden.

Du hast es dennoch - Zufall oder nicht - fast richtig gemacht. 
Allerdings:

fragender schrieb:
> Danach warte ich einen Flankenwechsel von Masterclk.
Nein, Du "wartest" auf die fallende Flanke. Du muss entweder den neueren 
Wert auf 1 oder den alten auf 0 abprüfen.

Sauber und sicher schreibt man das lieber ausdrücklich hin:

if (sig_m_clk_new = 1) and (sig_m_clk_old= 0) then

Eine kleine Frage: Wie willst Du eigentlich die Bits einsammeln?

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


Lesenswert?

fragender schrieb:
> Ich warte auf eine steigende Flanke  vom SYS_CLK.

> if SYS_CLK'event and SYS_CLK = '0' then

Sieht aber eher nach fallend aus

von T. K. (tntbc)


Lesenswert?

Hallo ich habe mich mal eingeloggt fragender(ICH),

ich danke euch für eure  super Beiträge. Ich habe jetzt den code 
geändert und eure Vorschläge eingearbeitet.

Lothar M. schrieb:
>> Hätte zwar nie gedacht das es bei den Frequenzen schon Probleme gibt
> Für "das Problem" reichen 2 Flipflops, 1 Taktflanke, und 1 Signal. Der
> Takt kann also beliebig langsam sein. Es tritt dann nur nicht "so
> häufig"  auf...

Ich habe jetzt diesen process vorab erzeugt der die Signale einsynct:
1
SYNC: process
2
begin
3
wait until rising_edge(SYS_CLK);
4
  S_CLK_SYNC <= S_CLK_SYNC(0) & M_CLK;
5
  S_MISO_SYNC <= S_MISO_SYNC(0) & MOSI;
6
  S_CS_SYNC <= S_CS_SYNC(0) & M_CS;
7
end process SYNC;
damit ist das Problem in der tat weg :/ Aber eine frage dazu:
Muss ich das ebenfalls mit Signalen zwischen Architekturen machen? In 
deinem Artikel steht alles unter 200 Mhz ist unkritisch.

Jürgen S. schrieb:
> Nein, Du "wartest" auf die fallende Flanke. Du muss entweder den neueren

Richtig! Ich habe auch deine Vorschlag eingearbeitet.



Jürgen S. schrieb:
> Eine kleine Frage: Wie willst Du eigentlich die Bits einsammeln?

JA will ich :) aber ein schritt nach dem anderen
der process sieht jetzt so aus:
1
STATE: process
2
begin
3
  wait until rising_edge(SYS_CLK);
4
    S_MCLK_OLD <= S_CLK_SYNC(1);
5
    if S_CS_SYNC(1)='0' then --cs ist nicht da!
6
      S_BIT_CNT <= BIT_LAENGE-1;
7
    else --cs aktive es geht los  
8
      if (S_MCLK_OLD = '1') and (S_CLK_SYNC(1)='0') then --fallende Flanke wird gesucht!
9
        S_RXDATEN <= S_RXDATEN(BIT_LAENGE-2 downto 0) & S_MISO_SYNC(1);
10
        M_TMP <= S_MISO_SYNC(1);
11
        if S_BIT_CNT = 0 then 
12
          RX_FINISH <= '1';
13
          S_BIT_CNT <= BIT_LAENGE-1;
14
        else
15
          S_BIT_CNT <= S_BIT_CNT-1;
16
          RX_FINISH <= '0';
17
        end if;
18
      else
19
        
20
      end if;
21
    end if;
22
end process STATE;
jetzt sehe ich auf dem oszi keine fehler mehr!

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


Lesenswert?

T. K. schrieb:
> damit ist das Problem in der tat weg
War ja einfach...

> Muss ich das ebenfalls mit Signalen zwischen Architekturen machen? In
> deinem Artikel steht alles unter 200 Mhz ist unkritisch.
Nicht ganz richtig. Dort steht, dass bis 200Mhz Metastabilität kein 
Problem machen wird. Deshalb reicht dort zum Synchronisieren 1Flipflop 
aus.

Du musst das Einsynchronisieren aber immer überall dort machen, wo du 
Taktdomänen überbrückst. Also auf jeden Fall bei externen Signalen, die 
asynchron zum FPGA Takt sind. Das sind z.B. immer irgendwelche Taster 
oder Sensoren.

von T. K. (tntbc)


Lesenswert?

Hallo Lothar,

Lothar M. schrieb:
> Problem machen wird. Deshalb reicht dort zum Synchronisieren 1Flipflop
> aus.

Ok das bedeutet also wenn ich das richtig verstehe. Ich benötige kein 
Schieberegister. Jedoch ist ein process wo die Eingänge mit der SYSCLK 
sync auf Architektur Signal gemapt werden nicht schlecht? Siehe Code:

1
entity bla is
2
port(
3
CLK: in std_logic;
4
hallo: in std_logic;
5
);
6
end bla;
7
8
architecture VERHALTEN of bla is
9
signal S_HALLO_SYNC: std_logic := '0';
10
begin
11
12
13
SYNC: process
14
wait until rising_edge(CLK);
15
S_HALLO_SYNC <= hallo;
16
end VERHALTEN;
17
18
19
MAIN: process
20
begin
21
 wait until rising_edge(CLK);
22
 if S_HALLO_SYNC = '0' then
23
..

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


Lesenswert?

T. K. schrieb:
> Jedoch ist ein process wo die Eingänge mit der SYSCLK sync auf
> Architektur Signal gemapt werden nicht schlecht?
Nein was soll daran "schlecht" sein?

Die Fragenstellung an sich deutet allerdings darauf hin, dass du immer 
noch "programmierst"...

Der richtige Ansatz wäre aber, zu sehen, dass da 1 Flipflop nötig ist. 
Und ab hier gibt es mehrere Wege, so ein Ding zu beschreiben. Einen 
davon hast du verwendet, man könnte auch ohne Prozess so schreiben:
S_HALLO_SYNC <= hallo when rising_edge(clk);

Oder du machst das einfach mit im MAIN Prozess:
1
MAIN: process
2
begin
3
  wait until rising_edge(CLK);
4
  S_HALLO_SYNC <= hallo
5
  if S_HALLO_SYNC = '0' then
6
    ...

: Bearbeitet durch Moderator
von T. K. (tntbc)


Lesenswert?

Lothar M. schrieb:
> Nein was soll daran "schlecht" sein?

Ok das war auch so gemeint das es nicht schlecht sein kann das zu 
machen.

Vielen dank an alle 16Mbit/s gehen jetzt ohne Probleme. Sich jedoch von 
der Programmierwelt zu verabschieden und in anderen Dimensionen zu denke 
fällt noch etwas schwer.  :)

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


Lesenswert?

T. K. schrieb:
> Sich jedoch von der Programmierwelt zu verabschieden
Musst du gar nicht, du musst eine Dimension ignorieren, nämlich die Zeit 
und damit die Position eines Befehls.

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.