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
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'andup='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.
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
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.
Ich habe den VHDL-Code trotzdem mal sicherheitshalber umgeschrieben,
damit die rising_edge-detection VHDL konform ist. Bringt aber keinen
Unterschied im Ergebnis.
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
Hier mal ein kleines Beispiel:
Ich habe in meinem Toplevel folgende Signale definiert:
1
SIGNALsig_up,sig_down:STD_LOGIC:='0';
2
SIGNALsig_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
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?
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. :-(
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
ENDIF;
5
6
IF(rising_edge(down))
7
THEN
8
up_dn_signal<='0';
9
ENDIF;
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<=upORdown;-- Aber holla! Kombinatorische Takte... :-o
2
edge_detection<=upORdown;
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
ENDIF;
13
14
IF(down='1')THEN
15
up_dn_signal<='0';
16
ENDIF;
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?
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?
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
entityTOPLEVELis
2
Port(signal_in:inSTD_LOGIC;
3
);
4
endTOPLEVEL;
5
6
architectureBehavioralofTOPLEVELis
7
8
COMPONENTDETEKTOR
9
Port(signal_1:inSTD_LOGIC;
10
up:outSTD_LOGIC;
11
down:outSTD_LOGIC
12
);
13
ENDCOMPONENT;
14
15
COMPONENTPulsformer
16
Port(up:inSTD_LOGIC;
17
down:inSTD_LOGIC;
18
clk:outSTD_LOGIC;
19
up_dn_signal:outSTD_LOGIC
20
);
21
ENDCOMPONENT;
22
23
SIGNALsig_up,sig_down:STD_LOGIC:='0';
24
SIGNALsig_clk,sig_ud_direction:STD_LOGIC:='0';
25
26
begin
27
28
DETEKTOR01:DETEKTOR
29
PortMap(signal_1=>signal_in,
30
up=>sig_up,
31
down=>sig_down
32
);
33
34
PULSFORMER:Pulsformer
35
PortMap(up=>sig_up,
36
down=>sig_down,
37
clk=>sig_clk,
38
up_dn_signal=>sig_ud_direction
39
);
40
41
endBehavioral;
Bringt das dem ein oder andere etwas weiter?
Gruß,
Spyro
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.
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?
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
entityd_flipflopis
2
Port(signal_in:inSTD_LOGIC;
3
rst:inSTD_LOGIC;
4
Q:outSTD_LOGIC
5
);
6
endd_flipflop;
7
8
architectureBehavioralofd_flipflopis
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
ENDIF;
22
23
ENDPROCESS;
24
25
26
endBehavioral;
Das Problem an der Implementierung ist der besagte 'U' Zustand.
Ich habe das nun folgendermaßen gelöst:
1
entityd_flipflopis
2
Port(signal_in:inSTD_LOGIC;
3
rst:inSTD_LOGIC;
4
Q:outSTD_LOGIC
5
);
6
endd_flipflop;
7
8
architectureBehavioralofd_flipflopis
9
10
SIGNALq_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
ENDIF;
24
25
ENDPROCESS;
26
27
Q<=q_out;
28
29
endBehavioral;
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
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.
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)... ;-)
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...
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 :)
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?" ;-)