Hi,
seit zwei Tagen zerbreche ich mir mittlerweile den Kopf, wie ich eine
StateMachine aufsetze, die durch einen externen Impuls ans Laufen
gebracht wird. Konkret will ich nur über 4 Werte mitteln, wobei 3 davon
nacheinander eintreffenden und der vierte das Ergebnis der vorherigen
Mittelung ist.
Mit Blick auf http://www.lothar-miller.de/s9y/categories/37-FSM habe ich
mein Glück versucht^^ vorher hatte ich noch andere Gehversuche, die sich
zwar wunderbar mit ghdl simulieren ließen, aber allesamt an
gescheitert sind.
Mein aktueller Versuch sieht sinngemäß so aus:
1
signalnew_data_available:std_logic:='0';
2
3
Averaging:process
4
begin
5
waituntilrising_edge(clk);
6
casestateis
7
whenreset=>--alles auf 0
8
whenidle=>--nur warten
9
whenstart=>
10
new_data_available<='0'--verursacht einen Fehler
11
state<=etc...
12
whenetc...
13
endcase;
14
15
if(rst='1')then
16
state<=reset;
17
elsif(new_data_available='1')then
18
state<=start;
19
endif;
20
endprocess;
21
22
NewData:process(v_in_new)
23
begin
24
if(rising_edge(v_in_new))then
25
new_data_available='1';
26
endif;
27
endprocess;
Meine Hoffnung bestand natürlich darin, dass ich so der Fehlermeldung
von oben entkomme, aber jetzt erhalte ich eine "andere". Die Simulation
setzt mir ab dem Zeitpunkt zu dem new_data_available auf '0' zurück
gesetzt wird den new_data_available auf 'u' :/
Kann mir da wer 'nen Tipp geben wie das unter einen Hut kriege? Meine
Phantasie stößt so langsam an ihre Grenzen :)
Danke,
Thorsten
Das wäre ein Dual-Clock-Flipflop. Hast du sowas schon mal gesehen?
Zudem sieht das zweitere verdächtig böse nach einem asynchronen Eingang
aus. Und jeder asynchrone Eingang muss erst mal irgendwie
einsynchronisiert werden!
> Meine Hoffnung bestand natürlich darin, dass ich so der Fehlermeldung> von oben entkomme
Ja, wenn die Hoffnung nicht wäre...
> Kann mir da wer 'nen Tipp geben wie das unter einen Hut kriege?
Und was ist dein Ziel?
Was sollen die Signale machen und bewirken?
Kannst du da mal ein Timingdiagramm/Ablaufdiagramm zeichnen?
Abgesehen von dem, was Lothar bereits schrieb, versuchst du hier
"new_data_available" in zwei verschiedenen Prozessen zu verändern. Und
das geht auch schief.
Lothar Miller schrieb:> Was sollen die Signale machen und bewirken?> Kannst du da mal ein Timingdiagramm/Ablaufdiagramm zeichnen?
Timingdiagramm inkl. Code habe ich mal angehängt. Das ist allerdings
noch meine vorherige Codeversion. Da wird beim Übersetzen auch
gemeckert, aber die Simulation zeigt genau das was ich haben will.
> Und jeder asynchrone Eingang muss erst mal irgendwie> einsynchronisiert werden!http://www.lothar-miller.de/s9y/archives/41-Einsynchronisieren-von-asynchronen-Signalen.html
habe ich schon gelesen, das Problem dahinter auch verstanden, aber
zwischen Problem verstanden und Abhilfe schaffen, ist's noch ein
Schritt, der mir noch nicht aufleuchtet.
> Und was ist dein Ziel?
...mein Problem ist, dass
ff2 doch auch wieder an clk hängt und ich das aus der FSM heraus dann
wieder nicht zurücksetzen könnte. Die Frage ist also letztlich wie ich
das dann trotzdem mache? Schreibe ich mir da einen Zähler, der ff2_out
und ff1_out wieder auf '0' setzt? Oder gibt es noch andere
Möglichkeiten?
Ja und jetzt seh ich's erst. Dein Beispiel fängt doch keine Peaks am
Eingang von ff1 ab. Aber genau das möchte ich ja....
D-Flipflop. Man man man, sorry für die Blöderlasfragen^^
Ich glaube, bis jetzt konnte keiner hier so recht verstehen, was du
eigentlich willst.
Du willst ne FSM machen, die irgendwas tut und bastelst da wilde
Konstruktionen mit Registern in mehreren Prozessen.
"Ordentlich" macht man sowas, indem man dem gesamten Design einen
Systemtakt verpasst. Dieser Takt taktet ALLE Register (ausnahmslos)
Deine eingehenden Signale werden dann wie Daten interpretiert. Wenn du
eine steigende Flanke auf einem eingehenden Signal erkennen willst, dann
schiebst du das Signal durch zwei Register und vergleichst, ob das eine
auf Low und das andere auf High ist. Damit hast du die Flanke erkannt.
Ja ne, ein D-FF reicht mit dem Takt nur das weiter was am Eingang
anliegt. Wenn mein Peak abgeklungen ist, kann er auch nicht
weitergereicht werden.
Schlumpf schrieb:> Wenn du eine steigende Flanke auf einem eingehenden Signal erkennen> willst, dann schiebst du das Signal durch zwei Register und vergleichst,> ob das eine auf Low und das andere auf High ist. Damit hast du die> Flanke erkannt.
Und damit fange ich "Peaks" ab? Also Eingangssignale, die kürzer als
mein clk sind?
Thorsten S. schrieb:> Und damit fange ich "Peaks" ab?
Ach so, ist jetzt ein Peak das Problem? Ich dachte, dein problem sei,
dass du ne FSM hast, die nicht laufen will, weil du da irgendeine
volgelwilde Konstrunktion mit mehreren Takten hast.
Aber Peaks kann man auch abfangen, indem man den Eingang durch mehrere
Register schiebt und z.B. einen Mehrheitsentscheid macht.
Aber auch hier gilt: Alle Register arbeiten schön brav mit dem
Systemtakt
Oder willst du auf Peaks reagiere?
Sorry, ich versteh nicht, was du eigentlich vor hast. Und deinen Code
mag ich mir beim besten Willen nicht anschauen.
Formuliere doch einfach mal in ein paar zusammenhängenden Sätzen, was
dein Design können soll, dann kann man dir hier auch sicher helfen
Schlumpf schrieb:> Oder willst du auf Peaks reagiere?> Sorry, ich versteh nicht, was du eigentlich vor hast. Und deinen Code> mag ich mir beim besten Willen nicht anschauen.> Formuliere doch einfach mal in ein paar zusammenhängenden Sätzen, was> dein Design können soll, dann kann man dir hier auch sicher helfen
Dann versuche ich's nochmal^^
1
v_in_new:instd_logic;--soll als Peak interpretiert werden
2
v_in:inunsigned(11downto0);--hier sind dann die Werte die v_in_new ankündigt
Wenn ich es mir recht überlege, dürfte es von den zeitlichen Abläufen
her vollkommen ausreichend sein, wenn ich mit dem Systemtakt nachschau,
ob v_in_new = '1' ist, sprich ich könnte das auch in die FSM
verschieben. Aber ich würde schon gerne wissen, wie ich das asynchroner
hinbekomme.
Man nehme ein flankengesteuertes RS-FF bei dem v_in_new auf S liegt und
dieses im Falle eines Peaks auf '1' setzt. Zurückgesetzt wird das FF
über R, was mit dem clk verbunden ist. Der Ausgang von diesem FF geht in
ein weiteres D-FF das ich von der FSM aus abfrage.
Das wäre jetzt mein analoger Ansatz (Verzögerungen etc. außen vor
gelassen). War das einigermaßen verständlich?
Das von dir angesprochene Schieberegister habe ich mittlerweile auch
gefunden,
http://www.lothar-miller.de/s9y/categories/18-Flankenerkennung
aber mit Peaks könnte ich damit nicht handhaben oder?
So, es hat ewig gedauert, aber ich habe mein eigentliches Problem
endlich gelöst und jetzt kann ich es auch in Worte fassen :D
Nochmal zur Situation: Ich habe ein asynchrones Eingangssignal, das mir
neue Daten meldet. Damit ich die Daten nur 1x lese, dachte ich mir ich
triggere auf eine steigende Flanke und ob das Signal dann 5 oder 50 ns
lang high ist, kann mir dann egal sein. Und hier hatte ich mich dann
verrannt.
Das Schieberegister hat mich dann vom Flankentriggern abgebracht, aber
der mehrmalige Durchlauf der FSM war noch nicht unterbunden.
1
signalinsr:std_logic_vector(2downto0);
2
:
3
processbegin
4
waituntilrising_edge(clk);
5
-- Schieberegister
6
insr<=insr(1downto0)&input;
7
endprocess;
8
9
processbegin
10
waituntilrising_edge(clk);
11
if(insr(2downto1)="10")then
12
-- fallende Flanke von input
13
new_data_available<='0';
14
endif;
15
if(insr(2downto1)="01")then
16
-- steigende Flanke von input
17
new_data_available<='1';
18
endif;
19
endprocess;
Dazu bedurfte es noch eines weiteren Bits und die Sache war gegessen.
1
:
2
endcase;
3
4
if(rst='1')then
5
state<=reset;
6
elsif(new_data_available='1'andstate=idle)then
7
triggered<='1';
8
if(triggered='0')then
9
state<=inc;
10
endif;
11
elsif(new_data_available='0')then
12
triggered<='0';
13
endif;
14
endprocess;--FSM
Nochmals Danke für die Beiträge...auch wenn mich keiner verstanden hat^^
geholfen hat's mir trotzdem ;)
Thorsten S. schrieb:> Nochmal zur Situation: Ich habe ein asynchrones Eingangssignal, das mir> neue Daten meldet. Damit ich die Daten nur 1x lese, dachte ich mir ich> triggere auf eine steigende Flanke und ob das Signal dann 5 oder 50 ns> lang high ist, kann mir dann egal sein. Und hier hatte ich mich dann> verrannt.
In einem solchen Fall sollte man die Funktionalität trennen.
Du schreibst Dir
a) ein Modul, das das Eingangssignal einsynchronisiert und bei einer
Flanke am Ausgang einen Puls mit genau einer Taktperiode High liefert
b) die FSM, die auf diesen Puls reagiert und die Verarbeitung macht
Thorsten S. schrieb:> im Falle eines Peaks
Was ist ein Peak?
Willst du eher einen "Spike" erkennen können (also einen Impuls, der
fürs reguläre Eintakten zu kurz ist oder sein kann)?
Offensichtlich ja:
> ob das Signal dann 5 oder 50 ns lang high ist, kann mir dann egal sein.
Dann kannst du die Sache so angehen:
http://www.lothar-miller.de/s9y/categories/19-SpikePuls
Du willst glaub offensichtlich genau das, was Lothar vermutet hat.
Falls dein "new-data-avilable" Signal so kurz ist, dass du es nicht mit
dem Systemtakt erfassen kannst, dann mach es so, wie Lothar es
beschrieben hat.
Falls du aber sicherstellen kannst, dass das Signal länger als 2
Systemtakte ist, dann sample es mit dem Systemtakt ein und mach mit der
unter anderem von mir beschriebenen Methode eine Flankenerkennung.
Also schieben durch mehrere Register und vergleich der Registerinhalte.