Forum: FPGA, VHDL & Co. Verständnisproblem interprocess communication


von fragender (Gast)


Lesenswert?

Hallo,
ich habe eine Frage bezüglich eines Interprocess communication.
Ich habe ein Prozess der eine Byte aus einem Array liest und ein Prozess 
der Das gelesen Byte aus an einem Pin weiter gibt. Nun stehe ich vor dem 
Problem das der Simulator einen undefinierten zustand für den 
Ausgangspin hat. Erstmal der Code:
1
P_N_D: process(D_N_DATA,S_SYSCLK)
2
variable addr: integer := 0;
3
begin
4
  if S_SYSCLK'event and S_SYSCLK='1' then
5
    if D_N_DATA = '1' and D_N_DATA_SHD /= D_N_DATA then
6
      D_A_DATA <= BRAM(addr);
7
      if addr = 7 then
8
        addr := 0;
9
      else
10
        addr := addr+1;
11
      end if;
12
    end if;
13
    D_N_DATA_SHD <= D_N_DATA;
14
  end if;
15
end process P_N_D;
16
17
P_DIN: process(S_SYSCLK)
18
variable V_TMPA: std_logic_vector(8 downto 0);
19
variable ADDR: integer := 0;
20
variable V_SHIFT: natural := 0;
21
begin
22
  if S_SYSCLK'event and S_SYSCLK = '1' then
23
    if D_N_DATA_SHD = D_N_DATA and D_N_DATA = '1' then
24
      D_N_DATA <= '0';
25
    else
26
      if V_SHIFT > 0 then
27
        V_SHIFT := V_SHIFT - 1;
28
        D_IN <= D_A_DATA(V_SHIFT);
29
        
30
      else      
31
        V_SHIFT := 8;
32
        D_IN <= 'Z';
33
        D_N_DATA <= '1';
34
      end if;
35
36
    end if;
37
  end if;
38
end process P_DIN;

D_N_DATA und D_N_DATA_SHD sollen die beiden Prozesse untereinander 
Kontrollieren. Leider klappt das nur minder gut. Genau im Fall wo der 
erste Prozess die D_A_DATA aktualisiert habe ich das Problem, das die 
Bedingung im zweiten Prozess war wird. Ich weiß, dass ich das Problem 
umgehen kann in dem ich den ersten Prozess mit fallender Flanke bediene. 
Aber das wirkt auf mich eher wir eine gefrickelte und nicht wie eine 
richtige Lösung.

Ihr habe sicher eine paar gute ideen!

Vielen Dank

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


Lesenswert?

Vorneweg:
fragender schrieb:
> P_N_D: process(D_N_DATA,S_SYSCLK)
D_N_DATA ist in der Sensitivliste nicht nötig. Es ist nur der Takt 
nötig.

fragender schrieb:
> variable addr: integer := 0;
> variable V_TMPA: std_logic_vector(8 downto 0);
> variable ADDR: integer := 0;
> variable V_SHIFT: natural := 0;
Warum so viele Variablen? Ich würde empfehlen erst mal überhaupt keine 
einzige Variable zu nehmen...

Warum uneingeschränkte Integer und Natural? So kann der Simulator 
niemals einen Überlauf oder eine Bereichsverletzung erkennen und melden.

Und jetzt zum eigentlichen Problem:
fragender schrieb:
> Genau im Fall wo der erste Prozess die D_A_DATA aktualisiert habe ich
> das Problem, das die Bedingung im zweiten Prozess war wird
Dein Ansatz, das Problem zu lösen ist falsch. Du willst hier irgendwie 
"Prozesse interagieren lassen". VHDL ist aber keine 
"Prozessinteraktionssprache", sondern eine 
"Hardwarebeschreibungssprache".
Was du da also beschrieben hast, sind getaktete D-Flipflops mit Logik 
dazwischen. Und die können ihren Zustand immmer nur mit einem Takt 
ändern, und übernehmen dann den Wert, der zu diesem Zeitpunkt am Eingang 
anliegt.

Du brauchst also ein "Bild" deiner Zielhardware. Und dieses 
beschreibst du dann mit VHDL. Also: was soll denn da passieren?

fragender schrieb:
> Genau im Fall wo der erste Prozess die D_A_DATA aktualisiert habe ich
> das Problem, das die Bedingung im zweiten Prozess war wird.
Verstehe ich jetzt nicht, ich vermute aber, das läuft letztlich auf 1 
Takt Latency raus, weil erst beim nächsten Takt der P_DIN den "neuen" 
Wert der an die im P_N_D zugewiesenen Signale verwendet.

> Ich weiß, dass ich das Problem umgehen kann in dem ich den ersten
> Prozess mit fallender Flanke bediene.
Das wäre fast schon ein Kündigungsgrund... :-/
Letztlich verdoppelst du damit einfach deine Taktfrequenz.

fragender schrieb:
> Nun stehe ich vor dem Problem das der Simulator einen undefinierten
> zustand für den Ausgangspin hat.
Wo? Lass sehen...

BTW:
1
if D_N_DATA = '1' and D_N_DATA_SHD /= D_N_DATA then
2
D_A_DATA <= BRAM(addr);
3
D_N_DATA_SHD <= D_N_DATA;
4
end process P_N_D;
Dir ist schon klar, dass es kaum noch nichtssagendere und unleselichere 
Namen gibt?

BTW2:
Warum brauchst/nimmst du da 2 Prozesse?

: Bearbeitet durch Moderator
von fragender (Gast)


Lesenswert?

Vielen Dank für deine Antwort.

Ich verstehe einige Erklärungen nicht.

Lothar M. schrieb:
> "Prozesse interagieren lassen". VHDL ist aber keine
> "Prozessinteraktionssprache", sondern eine
> "Hardwarebeschreibungssprache".

versuche ich nicht immer unter verschiedenen Architekturen zu 
kommunizieren? Daher unter verschiedenen Prozessen? Bsp Daten von SPI in 
den RAM schreiben oder Befehle von UART an die State-Maschine? Oder noch 
besser Daten vom ADC -> Filter -> PI-Control -> PWM
Wie synct man das?


Lothar M. schrieb:
> Das wäre fast schon ein Kündigungsgrund... :-/
> Letztlich verdoppelst du damit einfach deine Taktfrequenz.

:S ich weiß!!! :D

Lothar M. schrieb:
> Dir ist schon klar, dass es kaum noch nichtssagendere und unleselichere
> Namen gibt?
da gebe ich dir durchaus recht.

Lothar M. schrieb:
> Verstehe ich jetzt nicht, ich vermute aber, das läuft letztlich auf 1
> Takt Latency raus, weil erst beim nächsten Takt der P_DIN den "neuen"
> Wert der an die im P_N_D zugewiesenen Signale verwendet.

Genau das ist mein Problem der Simulator macht da etwas seltsamen. 
Normalerweise, werden Signale erst nach Beendigung des Prozesses 
geändert. Aber der zweite Prozess sieht das im gleichen Takt. Ich weiß 
dass man dies durchaus in einem Prozess verbauen kann. Aber genau das 
ist die Herausforderung. Zwei Prozesse die mit einander Syncron 
arbeiten.

Danke

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


Lesenswert?

fragender schrieb:
> versuche ich nicht immer unter verschiedenen Architekturen zu
> kommunizieren?
Schon. Aber eine "Architektur" ist tendenziell eher ein komplettes 
Modul, eine Einheit (=entity). Auch das Schlüsselwort "architecture" 
deutet darauf hin.
> Daher unter verschiedenen Prozessen?
Diese "Prozesse" sind ja in der Hardware letztlich nur ein paar 
Flipflops, die miteinander verbunden werden.

> Bsp Daten von SPI in den RAM schreiben oder Befehle von UART an die
> State-Maschine? Oder noch besser Daten vom ADC -> Filter -> PI-Control
> -> PWM
> Wie synct man das?
Der wichtigste "Synchronisator" ist der (im Idealfall einzige) Takt.
Darüber hinaus gibt es Valid-Signale, die jeweils für einen Taktzyklus 
lang anzeigen, dass jetzt (neue) Daten gültig sind. Oder Flags, die 
einen Zyklus lang anzeigen, dass z.B. eine bestimmte Aktion ausgelöst 
werden muss (z.B. ein Millisekunden-Flag).

> Normalerweise, werden Signale erst nach Beendigung des Prozesses
> geändert. Aber der zweite Prozess sieht das im gleichen Takt.
Der Ablauf in einem synchronen Design ist immer der selbe:
die Flipflops übernehmen durch eine Taktflanke den Eingangswert und 
speichern ihn als Ausgangswert. Darauf hin wird es hecktisch: die 
Kombinatorik ermittelt neue Eingangswerte für die Flipflops. Rechtzeitig 
(Stichwort Setupzeit) vor dem nächsten ist ruhe und mit dem nächsten 
Takt geht das spiel von vorn los.
Das passiert in der untersten Ebene, auf der Hardware im FPGA. In deinem 
Design erkennst du die Flipflops daran, dass sie getaktet Werte 
speichern. Also werden aus deinen "Variablen"-Zählern FLipflops und aus 
den Signalen, denen du einen Wert zuweist, werden Flipflops.

> Genau das ist mein Problem der Simulator macht da etwas seltsamen.
Der Simulator macht es in den allermeisten Fällen genau so, wie du es 
beschrieben hast.
> Normalerweise, werden Signale erst nach Beendigung des Prozesses
> geändert
Du siehst doch im Simulator das "Ende eines Prozesses" überhaupt nicht, 
weil so ein Prozess sowieso in der Zeit 0 berechnet wird. Wie gesagt: 
zeig einfach mal einen Screenshot vor der fraglichen Stelle.

von fragender (Gast)


Angehängte Dateien:

Lesenswert?

Hallo

vielen Dank für deine Antwort,

anbei das Bild. Genau da wo der Cursor ist sieht man, dass die Werte in 
D_A_DATA übernommen wurden aber D_IN ein 'U' ausgibt und erst im 
Anschluss die erste '1'

Danke

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


Lesenswert?

fragender schrieb:
> anbei das Bild.
Passt soweit. Genu da wo der Cursor steht ist im P_DIN die erste 
if-Bedingung erfüllt. D_IN wird dort gar nicht angefasst, kann sich zu 
diesem Zeitpunkt also auch nicht ändern. Und einen Takt später geht es 
in den else-Zweig mitsamt Zuweisung von Daten. so hast du es 
beschrieben...

U ist D_IN deshalb, weil jedes Signal gleich zu Beginn "Uninitialized" 
ist. Das wird dann offenbar nur einen kurz mit 'Z' "überschrieben", um 
dann wieder 'U' zu werden.

Es ist übrigens eine seltsame Idee, in einem getakteten Prozess einem 
Signal ein 'Z' zuzuweisen. Denn wie soll ein Flipflop dieses "hochohmig" 
denn speichern können (wie gesagt: Zuweisung mit Takt = Flipflop)? Ich 
auf jeden Fall kenne kein Flipflop, das das kann. Zumindest nicht im 
Inneren eines FPGAs.

Irgendwie stimmt hier dein Konzept noch nicht. Zeichne doch mal auf, wie 
du das Problem mit Logikbauteinen lösen würdest. Und beschreibe dann 
diese Skizze.

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.