Forum: FPGA, VHDL & Co. Signalzuweisung in Prozeß


von vhtl (Gast)


Lesenswert?

Ich stehe gerade auf dem Schlauch. Ich möchte beim Wechsel des Signals S 
eine Aktion ausführen. Kann ich da
1
Port ( S : in std_logic );
2
signal olds std_logic;
3
4
P: process(CLK)
5
begin
6
  if rising_edge(CLK) then
7
    olds <= S;
8
    if (S != olds) then
9
      -- Aktion
10
    end if;
11
  end if;
12
end process;

sinnvoll schreiben, oder haben S und olds nach der Zuweisung immer den 
gleichen Wert?

Ich dachte, daß bei Signalen die Änderung erst beim nächsten CLK wirksam 
wird, habe aber auch andere Beispiele (unbekannter Qualität) gesehen.

von Md M. (Firma: Potilatormanufaktur) (mdma)


Lesenswert?

vhtl schrieb:
> Ich möchte beim Wechsel des Signals S
> eine Aktion ausführen

Sicher, dass du weißt, was du meinst? Das, was du da machst ist 
taktsynchron. Es passiert was bei steigender Taktflanke. Das, was 
passiert, ist dann lediglich abhängig von S, aber nicht durch S 
getriggert.

> sinnvoll schreiben, oder haben S und olds nach der Zuweisung immer den
> gleichen Wert?

S ist ein Eingangssignal und ist davon abhängig, was da von außen 
anliegt. Alles (vom Prinzip her) gut, so wie es da steht, meine ich.

> Ich dachte, daß bei Signalen die Änderung erst beim nächsten CLK wirksam
> wird, habe aber auch andere Beispiele (unbekannter Qualität) gesehen.

Es kommt halt drauf an, ob du etwas im taktsynchronen Umfeld, also in 
einem Prozess mit CLK in der Sensivitätsliste machst.

Wieso simulierst du dir das nicht einfach?

: Bearbeitet durch User
von vhtl (Gast)


Lesenswert?

Ja, das ist taktsynchron gemeint. Eigentlich geht es mir um das 
Gegenteil, also ob das Signal S über zwei Takte hinweg konstant 
(punktuell gemessen natürlich) ist. Ich fand das Beispiel oben aber 
verständlicher.

Die Zuweisung olds <= S; wirkt also nicht "auf den Rest des Prozesses".

von Md M. (Firma: Potilatormanufaktur) (mdma)


Angehängte Dateien:

Lesenswert?

vhtl schrieb:
> Ich dachte, daß bei Signalen die Änderung erst beim nächsten CLK wirksam
> wird, habe aber auch andere Beispiele (unbekannter Qualität) gesehen.

Habs mal mit einer tesbench simuliert. Das Signal ist natürlich auch 
außerhalb des Prozesses da.

Code und so später, meine Freundin will jetzt Eis essen gehen :)

von Md M. (Firma: Potilatormanufaktur) (mdma)


Angehängte Dateien:

Lesenswert?

Das Design
1
library ieee;
2
use IEEE.std_logic_1164.all;    
3
4
entity mydesign is
5
6
  Port ( 
7
    S : in std_logic; 
8
    CLK : in std_logic
9
  );
10
11
end mydesign;
12
13
architecture RTL of mydesign is
14
15
  signal olds : std_logic;
16
17
begin
18
19
  P: process(CLK)
20
  begin
21
    if rising_edge(CLK) then
22
      olds <= S;
23
      if (S /= olds) then
24
        -- Aktion
25
      end if;
26
    end if;
27
  end process;    
28
29
end RTL;

Und die Testbench
1
library ieee;
2
use IEEE.std_logic_1164.all;    
3
4
entity tb_mydesign is
5
end tb_mydesign;
6
7
architecture tb_arch of tb_mydesign is
8
9
  component mydesign is
10
11
    port(
12
      S   : in std_logic;
13
      CLK : in std_logic
14
    );
15
16
  end component;
17
18
  signal tb_S   : std_logic := '0';
19
  signal tb_CLK : std_logic := '0';
20
21
begin
22
23
  tb_CLK <= not tb_CLK after 10417 ps;
24
  tb_S   <= not tb_S   after 104170 ps;
25
26
  dut : mydesign
27
28
  port map (
29
    S   => tb_S,
30
    CLK => tb_CLK
31
  );
32
33
end architecture;

Ein paar Fehler habe ich korrigiert. Bild mit korrigierten 
Signalbezeichnungen.

von vhtl (Gast)


Lesenswert?

Herzlichen Dank, aber die Simulation zeigt doch, daß ich NICHT recht 
habe. Ich nehme an, die Änderung der Reihenfolge bewirkt nichts.

Müßte ich dann
1
signal olds : std_logic_vector(1 downto 0);
2
...
3
olds <= olds(0) & S;
4
if olds(1) /= olds(0) then ...

schreiben?

von vhtl (Gast)


Lesenswert?

Wenn ich es recht bedenke, sagt die Simulation noch nichts.

Kannst Du bitte als Aktion ein S2 <= '1'; einführen, welches mit '0' 
initialisiert wird?

von e-wastl (Gast)


Lesenswert?

Servus,

ohne jetzt alles gelesen zu haben: Bei der Zuweisung

[vhdl]
olds <= S;
[vhdl]

bzw.

[vhdl]
olds <= olds(0) & S;
[vhdl]

wird der Wert von "olds" erst am Ende (!!!) des Prozesses zugewiesen.

Wenn du "olds" einen Wert zuweisen und gleich darauf verwenden willst 
(in der Abfrage) müsstest du mit Variablen arbeiten.

von e-wastl (Gast)


Lesenswert?

Servus,

nochmal richtig formatiert ;-).
1
olds <= S;

bzw.
1
olds <= olds(0) & S;

wird der Wert von "olds" erst am Ende (!!!) des Prozesses zugewiesen.

Wenn du "olds" einen Wert zuweisen und gleich darauf verwenden willst
(in der Abfrage) müsstest du mit Variablen arbeiten.

von Md M. (Firma: Potilatormanufaktur) (mdma)


Lesenswert?

vhtl schrieb:
> Herzlichen Dank, aber die Simulation zeigt doch, daß ich NICHT recht
> habe. Ich nehme an, die Änderung der Reihenfolge bewirkt nichts.

Ich verstehe nicht, was du meinst. Ich bin nach dem hier...

vhtl schrieb:
> Ja, das ist taktsynchron gemeint. Eigentlich geht es mir um das
> Gegenteil, also ob das Signal S über zwei Takte hinweg konstant
> (punktuell gemessen natürlich) ist.

...davon ausgegangen, dass du wissen wolltest, ob S nach änderung im 
Prozess seinen Wert behält, wenn der Prozess beendet ist. Und ja, das 
tut es und das geht aus der Simulation hervor.

vhtl schrieb:
> Wenn ich es recht bedenke, sagt die Simulation noch nichts.

Siehe. oben

vhtl schrieb:
> Kannst Du bitte als Aktion ein S2 <= '1'; einführen, welches mit '0'
> initialisiert wird?

Mach selbst ;-) Du wirst kaum effektiv vorankommen, wenn du nicht 
simulierst. Womit arbeitest du denn derzeit? Direkt auf Hardware? Kann 
doch nicht sein, dass du dein VHDL nur im Kopf laufen lässt.

von vhtl (Gast)


Lesenswert?

Ja, mein Code funktioniert! Ich habe einfach Deine Testbench genommen, 
wie man selbst eine schreibt wußte ich nicht.

Mir ging es darum, daß "olds <= S" gerade NICHT sofort aufgeführt wird. 
Ich hatte die erste Simulation zunächst so interpretiert, das dem so 
ist, das war aber falsch.

Danke euch also nochmals. Jetzt stimmt mein Weltbild wieder.

von Dussel (Gast)


Lesenswert?

Nur kurz nebenbei: S und olds sind std_logic. Die können viele 
verschiedene Werte haben. In deinem Beispiel würde das if auch 
ausgeführt, wenn sich S von zum Beispiel X, U oder H ändert.

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


Lesenswert?

vhtl schrieb:
> oder haben S und olds nach der Zuweisung immer den gleichen Wert?
Ein Signal behält seinen initialen Wert bis zum Ende des Prozesses (oder 
bis zum nächsten wait). Am Ende des Prozesses (oder beim nächsten wait) 
übernimmt das Signal den zuletzt zugewiesenen Wert. Das hier:
1
  P: process(CLK)
2
  begin
3
    if rising_edge(CLK) then
4
      olds <= S;
5
      if (S /= olds) then
6
        -- Aktion
7
      end if;
8
    end if;
9
  end process;
kannst du also (solange bei der "Aktion" dem olds nicht auch noch was 
zugewiesen wird) ohne jegliche funktionelle Änderung auch so schreiben:
1
  P: process(CLK)
2
  begin
3
    if rising_edge(CLK) then
4
      if (S /= olds) then
5
        -- Aktion
6
      end if;
7
      olds <= S;
8
    end if;
9
  end process;

Dussel schrieb:
> Nur kurz nebenbei: S und olds sind std_logic. Die können viele
> verschiedene Werte haben. In deinem Beispiel würde das if auch
> ausgeführt, wenn sich S von zum Beispiel X, U oder H ändert.
Das ist aber nur ein Simulationsproblem. In der Realität sind Signale 
nur low und high. Der neunwertige std_logic reduziert sich also 
"automatisch" auf '0' und '1'...

: Bearbeitet durch Moderator
von Dussel (Gast)


Lesenswert?

Lothar M. schrieb:
> Dussel schrieb:
>> Nur kurz nebenbei: S und olds sind std_logic. Die können viele
>> verschiedene Werte haben. In deinem Beispiel würde das if auch
>> ausgeführt, wenn sich S von zum Beispiel X, U oder H ändert.
> Das ist aber nur ein Simulationsproblem. In der Realität sind Signale
> nur low und high. Der neunwertige std_logic reduziert sich also
> "automatisch" auf '0' und '1'...
Ja, aber nicht dass es plötzlich unerklärliche Unterschiede zwischen 
Simulation und Realität gibt.

von Dussel (Gast)


Lesenswert?

Wenn man sichergehen will, kann man
1
signal olds : std_logic_vector(1 downto 0);
2
...
3
olds <= olds(0) & S;
4
if olds="01" then ...
schreiben. Dann detektiert man wirklich eine 01-Flanke (oder eine 
10-Flanke, wenn ich mich wieder vertan habe :-)

von vhtl (Gast)


Lesenswert?

Das hatte ich zuerst geschrieben, aber ist man dann nicht einen 
Taktzyklus hintendran mit der Detektion?

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


Lesenswert?

vhtl schrieb:
> Das hatte ich zuerst geschrieben, aber ist man dann nicht einen
> Taktzyklus hintendran mit der Detektion?
Du kannst jede Flanke erst einen Takt später detektieren. Zeichne dir 
einfach mal ein Bild auf.

Und wenn das Signal ein FPGA-Pin ist, dann empfiehlt es sich sehr, erst 
mal einzusynchronisieren. Sonst bastelst du wieder mal eines der 
Beispiele, die zeigen, warum man einsynchronisieren muss. Such dazu 
einfach mal hier im Forum nach "eintakten", "einsynchronisieren", 
"seltsame Effekte", "sporadische Fehler" usw...

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.