Forum: FPGA, VHDL & Co. VHDL-Pulsformer funktioniert alleine aber nicht als Component in Gesamtprojekt


von Spyro (Gast)


Angehängte Dateien:

Lesenswert?

Hi Leute,

ich habe folgenden Pulsformer:
1
entity Pulsformer is
2
  Port (  up          : in  STD_LOGIC := '0';
3
        down        : in  STD_LOGIC := '0';
4
        clk        : out  STD_LOGIC := '0';
5
        up_dn_signal  : out  STD_LOGIC := '0'
6
  );
7
end Pulsformer;
8
9
architecture Behavioral of Pulsformer is
10
11
begin
12
13
  clk <= up OR down;
14
  
15
  PROCESS(up, down)
16
  BEGIN
17
  
18
    IF(rising_edge(up))
19
    THEN
20
      up_dn_signal <= '1';
21
    END IF;
22
    
23
    IF(rising_edge(down))
24
    THEN
25
      up_dn_signal <= '0';
26
    END IF;
27
  
28
  END PROCESS;
29
30
end Behavioral;

Wenn ich den in der Testbench laufen lasse, dann funktioniert er wie 
beschrieben. Sobald ich den aber in eine entity als COMPONENT einbinde 
funktioniert er nicht mehr.

Ich habe zwei Screenshots aus der Simulation angehängt, damit klar wird 
was ich meine und wie der Dinger funktionieren soll.

Liegt das an dem 'U' State des einen Signals, dass der mein up_dn_signal 
nicht auf logisch '1' zieht?

Kann mir da jemand weiterhelfen?

Gruß,
Steffen

von Walleby (Gast)


Lesenswert?

Hi,

ich glaube das liegt daran, dass du zwei mal nach einer Flanke suchst.
Soweit ich weiß (bin mir aber nicht ganz sicher), solltest du in einem 
Prozess nur auf eine Flanke, also fallen oder steigend suchen.

Ich würde mal alternativ zwei Signale verwenden:
1
up_old <= up
2
3
if(up_old ='0' and up = '1') --Für steigende Flanke

Außerdem weist du deinen Eingangssignalen den Wert '0' zu. Das könnte 
ebenfalls zu Problemen führen. Du musst die eigentlich nicht setzten, da 
diese ja von aussen kommen.

von Spyro (Gast)


Lesenswert?

Hey Walleyby,

danke schonmal für die Antwort.
Das mit den zweimal rising_edge auf unterschiedliche Signale in einem 
Prozess ist unsauber, i know. Nimmt man an, dass beide Signale triggern, 
dann kommt es zu undefinierten Zuständen, deswegen soll man das 
unterlassen, da hast du Recht.
In meinem Fall ist eine gleichzeitige Flanke von up und down 
designtechnisch ausgeschlossen und kommt definitiv nicht vor.

Die Standardwerte für meine Ein- und Ausgangssignale habe ich gesetzt, 
damit der Simulator damit zurecht kommt. Der macht manchmal Probleme, 
wenn er keine Standardwerte hat. In diesem Fall kann ich es aber auch 
weglassen, das stimmt. Der Sim braucht das ja nur für Signale, die man 
definiert.

Gruß,
Steffen

von Walleby (Gast)


Lesenswert?

Kann es sein, dass du das Eingangssignal im Toplevel nicht mit deiner 
Komponente verbunden hast? 'U' zeigt dir ja an, dass es nicht 
initialisiert wurde.

von Spyro (Gast)


Lesenswert?

Ich habe den VHDL-Code trotzdem mal sicherheitshalber umgeschrieben, 
damit die rising_edge-detection VHDL konform ist. Bringt aber keinen 
Unterschied im Ergebnis.
1
entity Pulsformer is
2
  Port (  up          : in  STD_LOGIC;
3
        down        : in  STD_LOGIC;
4
        clk        : out  STD_LOGIC;
5
        up_dn_signal  : out  STD_LOGIC
6
  );
7
end Pulsformer;
8
9
architecture Behavioral of Pulsformer is
10
11
  SIGNAL edge_detection  : STD_LOGIC := '0';
12
13
begin
14
15
  clk         <= up OR down;
16
  edge_detection <= up OR down;
17
  
18
  PROCESS(edge_detection)
19
  BEGIN
20
  
21
    IF(rising_edge(edge_detection))
22
    THEN
23
    
24
      IF(up = '1') THEN
25
        up_dn_signal <= '1';
26
      END IF;
27
      
28
      IF(down = '1') THEN
29
        up_dn_signal <= '0';
30
      END IF;
31
      
32
    END IF;
33
  
34
  END PROCESS;
35
36
end Behavioral;

von Spyro (Gast)


Lesenswert?

Hey Walleby,

das ist ja das Komische.
Ich habe die Verdrahtung jetzt mind. 5-6mal überprüft und angeschlossen 
sind alle Komponenten genau so, wie sie es nach Schaltplan sein sollen.

Ich habe allen SIGNAL-Definitionen jeweils einen Standardwert übergeben, 
damit der Simulator auf Standardwerte zurückgreifen kann. Manchmal 
ignoriert er das aber trotzdem... sehr komisch...

Falls dir noch was einfällt immer her damit! Ich bin dankbar für jeden 
alternativen Gedankengang der mir gegeben wird.

Gruß,
Steffen

von Spyro (Gast)


Angehängte Dateien:

Lesenswert?

Hier mal ein kleines Beispiel:
Ich habe in meinem Toplevel folgende Signale definiert:
1
  SIGNAL sig_up, sig_down        : STD_LOGIC := '0';
2
  SIGNAL sig_clk, sig_ud_direction  : STD_LOGIC := '0';

Das Bild oben zeigt die Ausgabe des Simulators von Anfang an.
Da müssten doch alle vier Signale von Anfang an auf '0' sein, oder mache 
ich irgendwo einen Denkfehler?

Gruß,
Steffen

von Walleby (Gast)


Lesenswert?

Das ist komisch. Wenn du die Signale in deinem Toplevel '0' setzt, 
sollte eigentlich kein U dabei rauskommen.

Die Definition passt. Jedoch kommt von dem Signal nichts in deiner 
Komponente an, da alle Signale am Anfang nicht initalisisert sind. Ich 
tippe darauf, dass im Toplayer noch eine Verbindung nicht funktioniert 
bzw. du diese noch nicht richtig angeschlossen hast?

Was mir noch auffällt ist, dass du keinen Takt vorgibst. Der muss ja 
dann in einer anderen Komponente sein, der die Signale sig_up, sig_down 
toggelt oder?

von Bitflüsterer (Gast)


Lesenswert?

Die Raterei könnten wir uns sparen, wenn, wie in der Netiquette 
beschrieben, ein vollständiger, elaborierbarer und simulierbarer, 
minimaler Code gezeigt würde, der das Problem zeigt. Daneben fehlen auch 
Angaben zum verarbeitenden Programm und Simulator.

Immer das selbe Theater. :-(

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


Lesenswert?

Spyro schrieb:
> Sobald ich den aber in eine entity als COMPONENT einbinde funktioniert
> er nicht mehr.
Welche Zielplattform? CPLD, FPGA? Hersteller? Toolchain? Welche 
Warnungen (da gibt es garantiert einige!!)?

> Wenn ich den in der Testbench laufen lasse, dann funktioniert er wie
> beschrieben.
Du kannst 100% des Sprachumfangs von VHDL simulieren. Du kannst aber 
allerhöchstens 5% davon auf ein FPGA bringen. Sowas bekommst du niemals 
in ein FPGA:
1
    IF(rising_edge(up))
2
    THEN
3
      up_dn_signal <= '1';
4
    END IF;
5
    
6
    IF(rising_edge(down))
7
    THEN
8
      up_dn_signal <= '0';
9
    END IF;
Ein Dual-Clock-Flipflop gibts im FPGA nicht. Auch sonst im Leben gibt es 
das nicht. Obwohl... hmmm... man könnte da was mit einem Dual-Port-RAM 
machen. Aber ob das deine Absicht ist...

Und bei dem hier muss dir der Synthesizer dermaßen von so was auf die 
Finger klopfen:
1
  clk         <= up OR down;    -- Aber holla! Kombinatorische Takte... :-o
2
  edge_detection <= up OR down;
3
  
4
  PROCESS(edge_detection)
5
  BEGIN
6
  
7
    IF(rising_edge(edge_detection))
8
    THEN
9
    
10
      IF(up = '1') THEN        -- wie war das nochmal mit der Setup- und Hold-Time?
11
        up_dn_signal <= '1';
12
      END IF;
13
      
14
      IF(down = '1') THEN
15
        up_dn_signal <= '0';
16
      END IF;

Das hier ist ein zutiefst asynchrones Design. Sowas vermeidet man in der 
Praxis wie der Teufel das Weihwasser. Hast du nicht einen 100MHz 
Systemtakt oder sowas? Woher kommen die Signale und wohin gehen sie? 
Oder anders: WAS soll denn diese "Schaltung" überhaupt machen?

: Bearbeitet durch Moderator
von Paul B. (Gast)


Lesenswert?

die Funktion scheint mir ohnehin komisch, weil up und down den Takt 
vorgeben sollen, aber keine zeitliche Behandlung der Signale erfolgt.

so liesse es sich auch mit einem Gatter beschreiben, bei dem das up 
Vorrang gegenüber dem down hat, was sich auch nicht beabsichtigt ist.

Was soll denn z.B. in dem Fall geschehen, wenn beide high sind?

von Spyro (Gast)


Lesenswert?

Hey Leute,

schonmal danke soweit für jede Hilfestellung.

Kurze Info zu meiner Entwicklungsumgebung (bitte entschuldigt, dass ich 
das nicht gleich dazu gepostet habe, war so in der Entwicklung 
vertieft):
Xilinx ISE 14.7
Spartan 3E FPGA

Der Syntheziser und der Simulator geben keinerlei 
Warnungen/Verbose/Fehler/sontiges raus. Es wird alles fehlerfrei 
durchlaufen.

Es kommen zwei Signale rein, up und down.
Beide Signale treten nie gleichzeitig auf und es gibt auch keine 
Überschneidung der Signale. Das ist designtechnisch ausgeschlossen und 
geht nicht. Deswegen verwende ich auch kombinatorische Takte, da 
sichergestellt ist, dass nie beide Signale gleichzeitig auftreten.
Der clk-Ausgang des Pulsformers liefert einfach die Überlagerung der 
beiden up/down-Signale, deswegen die Veroderung.

Was soll das Ding können?
Der clk-Ausgang soll einfach die Überlagerung der Takte ausgeben.
Der up/down-signal - Ausgang soll bei einer rising_edge des up-Signals 
auf '1' springen und bei einer rising_edge des down-Signals auf '0' 
zurücksetzen.

Einen gemeinsamen Systemtakt gibt es für dieses Bauteil nicht.

Ich habe die wichtigen Teile aus dem Toplevel hier extrahiert.
1
entity TOPLEVEL is
2
  Port (  signal_in             : in  STD_LOGIC;
3
  );
4
end TOPLEVEL ;
5
6
architecture Behavioral of TOPLEVEL is
7
8
  COMPONENT DETEKTOR
9
  Port (  signal_1  : in  STD_LOGIC;
10
          up        : out  STD_LOGIC;
11
          down      : out  STD_LOGIC
12
  );
13
  END COMPONENT;
14
  
15
  COMPONENT Pulsformer
16
  Port (  up            : in  STD_LOGIC;
17
          down          : in  STD_LOGIC;
18
          clk           : out  STD_LOGIC;
19
          up_dn_signal  : out  STD_LOGIC
20
  );
21
  END COMPONENT;
22
  
23
  SIGNAL sig_up, sig_down           : STD_LOGIC := '0';
24
  SIGNAL sig_clk, sig_ud_direction  : STD_LOGIC := '0';
25
26
begin
27
28
  DETEKTOR01: DETEKTOR
29
  Port Map (  signal_1  => signal_in,
30
              up        => sig_up,
31
              down      => sig_down
32
  );
33
  
34
  PULSFORMER: Pulsformer
35
  Port Map (  up            => sig_up,
36
              down          => sig_down,
37
              clk           => sig_clk,
38
              up_dn_signal  => sig_ud_direction
39
  );
40
41
end Behavioral;

Bringt das dem ein oder andere etwas weiter?

Gruß,
Spyro

von eingast (Gast)


Lesenswert?

Deine Inputs scheinen Käse zu sein, da brauchst du nicht im Modul zu 
suchen. Kontrollier mal alle Warnings ob was nicht verbunden oder zwei 
oder mehr Treiber hat. Selbst wenn du sagst du hast das schon, bevor up 
und down nicht so aussieht wie es soll brauchst du nicht weiter zu 
machen.

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


Lesenswert?

Spyro schrieb:
> Was soll das Ding können?
> Der clk-Ausgang soll einfach die Überlagerung der Takte ausgeben.
> Der up/down-signal - Ausgang soll bei einer rising_edge des up-Signals
> auf '1' springen und bei einer rising_edge des down-Signals auf '0'
> zurücksetzen.
Du hast dir da also irgendein Latch aufgebaut. Sieh dir mal den RTL 
Schaltplan an...

> Einen gemeinsamen Systemtakt gibt es für dieses Bauteil nicht.
HAST du so einen Takt zur Verfügung?
Falls ja: warum machst du dann nicht einfach ein bombensicheres, 
stinklangweiliges, dafür aber funktionierendes synchrones Design?

von Spyro (Gast)


Lesenswert?

Lothar Miller schrieb:
> Du hast dir da also irgendein Latch aufgebaut. Sieh dir mal den RTL
> Schaltplan an...

Jetzt wo du es sagst, stimmt... das ist ein RS-Flipflop. Hätte man auch 
selbst drauf kommen können. Respekt an dich!

Lothar Miller schrieb:
> HAST du so einen Takt zur Verfügung?
> Falls ja: warum machst du dann nicht einfach ein bombensicheres,
> stinklangweiliges, dafür aber funktionierendes synchrones Design?

Ich habe zwar theoretisch so einen Takt zur Verfügung, kann ich aber 
nicht verwenden, weil es das gewollte Verhalten der Toplevelschaltung 
außer Kraft setzen würde.

eingast schrieb:
> Deine Inputs scheinen Käse zu sein, da brauchst du nicht im Modul zu
> suchen. Kontrollier mal alle Warnings ob was nicht verbunden oder zwei
> oder mehr Treiber hat. Selbst wenn du sagst du hast das schon, bevor up
> und down nicht so aussieht wie es soll brauchst du nicht weiter zu
> machen.

Es gibt keinerlei Errors, Warnings oder dergleichen beim Synthetisieren.
Ich habe auch die RTL Schematic überprüft und es ist alles korrekt 
verdrahtet.

Ich bin jetzt zumindest einen Schritt weiter und zwar habe ich im Design 
D-FlipFlops synthetisiert mit folgendem Code:
1
entity d_flipflop is
2
  Port (  signal_in  : in  STD_LOGIC;
3
          rst        : in  STD_LOGIC;
4
          Q          : out  STD_LOGIC
5
  );
6
end d_flipflop;
7
8
architecture Behavioral of d_flipflop is
9
10
begin
11
12
  PROCESS(signal_in, rst)
13
  BEGIN
14
  
15
    IF (rst = '1')
16
    THEN
17
      Q <= '0';
18
    ELSIF (rising_edge(signal_in))
19
    THEN
20
      Q <= '1';
21
    END IF;
22
  
23
  END PROCESS;
24
25
26
end Behavioral;

Das Problem an der Implementierung ist der besagte 'U' Zustand.
Ich habe das nun folgendermaßen gelöst:
1
entity d_flipflop is
2
  Port (  signal_in  : in  STD_LOGIC;
3
          rst        : in  STD_LOGIC;
4
          Q          : out  STD_LOGIC
5
  );
6
end d_flipflop;
7
8
architecture Behavioral of d_flipflop is
9
10
  SIGNAL q_out  : STD_LOGIC := '0';
11
12
begin
13
14
  PROCESS(signal_in, rst)
15
  BEGIN
16
  
17
    IF (rst = '1')
18
    THEN
19
      q_out <= '0';
20
    ELSIF (rising_edge(signal_in))
21
    THEN
22
      q_out <= '1';
23
    END IF;
24
  
25
  END PROCESS;
26
  
27
  Q <= q_out;
28
29
end Behavioral;

Alles Weitere muss ich alleine lösen.

Vielen, vielen Dank an alle die versucht haben mir zu helfen und mich in 
die richtige Richtung gestubst haben.

Ich wünsche noch eine angenehme Woche :)

Gruß,
Spyro

von Spyro (Gast)


Lesenswert?

Als kleine Anmerkung noch:
Ich konnte leider nicht mehr Code veröffentlichen, da mir dann 
möglichweise zu viel Arbeit von der Community abgenommen wird.
Grade deswegen nochmal vielen Dank für die Unterstützung.

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


Lesenswert?

Spyro schrieb:
> rising_edge(signal_in)
Ich zerreiße jedes Anfängerdesign, das mehr als 1 Takt hat (und 
derjenige, der das verbrochen hat keine sehr, sehr gute Ausrede findet 
[und die findet er nicht!]) hochkantig in der Luft. Warum? solche 
asynchronen Design sind Murks. Es geht nämlich sicher (und vor allem: 
für die Toolchain kalkulierbar) auch mit nur 1 Takt.

Denn das was du da hast wird in der Praxis niemals zuverlässig laufen, 
denn reagiert auf jeden klitzekleinen Glitch, der z.B. aus einer 
vorgelagerten Kombinatorik kommt.

> Ich habe zwar theoretisch so einen Takt zur Verfügung, kann ich aber
> nicht verwenden, weil es das gewollte Verhalten der Toplevelschaltung
> außer Kraft setzen würde.
Sagt wer?

> Ich wünsche noch eine angenehme Woche :)
Ich wünsche dir viel Glück (das brauchst du bei diesem Design) und einen 
innovativen Betreuer (der auf solchen VHDL Code steht)...  ;-)

von Achim S. (Gast)


Lesenswert?

Spyro schrieb:
> Jetzt wo du es sagst, stimmt... das ist ein RS-Flipflop.

Warum steuerst du es dann mit der Flanke von signal_in und nicht mit dem 
Pegel?

Da du dem Reset Vorrang über dem Set gibst, lässt es sich mit 
Pegelsteuerung direkt auf ein FDCPE (Flip Flop mit asynch Set/Clear) 
abbilden.

Spyro schrieb:
> Ich habe zwar theoretisch so einen Takt zur Verfügung, kann ich aber
> nicht verwenden, weil es das gewollte Verhalten der Toplevelschaltung
> außer Kraft setzen würde.

Na, dann hoffen wir mal, dass das alles gut durchdacht ist...

von Spyro (Gast)


Lesenswert?

Lothar Miller schrieb:
> Denn das was du da hast wird in der Praxis niemals zuverlässig laufen,
> denn reagiert auf jeden klitzekleinen Glitch, der z.B. aus einer
> vorgelagerten Kombinatorik kommt.

Kleiner Tipp:
Es würde nie zuverlässig laufen, wann man nicht irgendeine Art von 
Rückkopplung ins System einschleust die das ganze wieder stabilisiert ;)

So, jetzt bin ich ruhig und verziehe mich in meinen Anfängerkeller.
Schönen Abend noch :)

von bko (Gast)


Lesenswert?


von Schlumpf (Gast)


Lesenswert?

Irgendwie erstaunlich:
Man kann schon solche asynchronen Sachen machen, wenn man weiss, was man 
tut. Offensichtlich scheinst du das zu wissen, denn du sagst ja, dass du 
durch eine "wundersame" Rückkopplung alles ganz stabil hinbekommst.
Erkennst aber auf der anderen Seite nicht, dass du ein derart 
offensichtliches Latch eingebaut hast.
Wenn man solche asynchronen Sauereien macht, dann kennt man 
üblicherweise jedes Register/Latch, etc im FPGA persönlich. Denn anders 
bekommt man es nicht in den Griff.

Dann sagst du, dass du keinerlei Warnings bekommen hast.
Ich keine keinen Synthesizer, der nicht warnt, wenn ein Latch entsteht.

Aber wenn du wirklich sicher bist (oder glaubst, sicher zu sein), dann 
ist ja alles gut. Der Teufel steckt bei sowas im Detail. Und sicher, 
dass das Design funktioniert, ist man entweder, wenn man alle diese 
Details kennt und weiss, dass man sich beachtet hat, oder wenn man diese 
Details eben nicht kennt und daher glaubt, an alles gedacht zu haben.

Falls also dein Design immer wieder mal unerklärliche "Aussetzer" hat, 
oder bei einem Syntheselauf funktioniert und beim nächsten plötzlich 
nicht mehr, obwohl du an der fraglichen Stelle gar nichts geändert hast, 
dann relativieren sich vielleicht Lothars "harte Worte" zu "was hat er 
eigentlich genau damit gemeint?" ;-)

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.