Forum: FPGA, VHDL & Co. Bei Flankenerkennung Signal für einen Takt HIGH setzen


von quarks (Gast)


Lesenswert?

Hallo VHDL Profis,

ich habe ein ganz banales Problem und komme momentan einfach nicht 
drauf.

Ich habe ein clk - Signal und ein valid - Signal.

Nach einer bestimmten Zeit wird das valid Signal '1'. Nach 1000 clk wird 
das valid Signal dann wieder '0'. Ich möchte nun bei fallender Flanke 
des valid Signals ein eigenes Signal own_valid für einen Takt HIGH 
setzen.

Wie kann ich das am besten realisieren? Ich benötige doch einen Prozess 
mit clk und valid in der Sensitivitätsliste, oder? Nur wenn ich dann auf 
die aufsteigende Flanke des clk's triggere mit
1
process (clk)
2
begin
3
 if rising_edge (clk) then
4
   ....
5
 end if;
6
end process

dann kann ich doch nicht auf die fallende Flanke von valid das Signal 
own_valid = '1' setzen. Damit würde ich doch zwei Flip Flops generieren, 
welche irgendwie miteinander verschachtelt sind.

Also so:
1
process (clk, valid)
2
begin
3
 if rising_edge (clk) then
4
   if falling_edge (valid) then
5
     own_valid <= '1';
6
   else
7
     own_valid <= '0';
8
   end if;
9
 end if;
10
end process

Oder muss ich einen Zähler bauen, der nach 1000 Takten dann für 1 Takt 
den own_valid HIGH setzt?


Tut mir wirklich leid, dass ich eine so blöde Frage stellen muss.


Vielen Dank und Gruß

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


Lesenswert?

quarks schrieb:
> if rising_edge (clk) then
>    if falling_edge (valid) then
Aua. Was sollte denn das für ein Bauteil sein?
Und wie sollten diese beiden Flanke (mit einer theoretisch unendlich 
kurzen Zeitdauer) genau gleichzeitig kommen können?

quarks schrieb:
> Oder muss ich einen Zähler bauen, der nach 1000 Takten dann für 1 Takt
> den own_valid HIGH setzt?
Nein, du musst nur die fallende Flanke erkennen.
Dazu merkst du dir in jedem Takt den alten Wert und vergleichst den mit 
dem aktuellen Wert. Wenn der Wert vorher '1' war und jetzt '0' ist, dann 
ist das eine fallende Flanke:
1
process (clk, valid)
2
begin
3
 if rising_edge (clk) then
4
   if altes_valid='1' and valid='0' then
5
     own_valid <= '1';
6
   else
7
     own_valid <= '0';
8
   end if;
9
   altes_valid <= valid;
10
 end if;
11
end process

von tim (Gast)


Lesenswert?

wozu braucht es den das valid in der sensitivity list?

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


Lesenswert?

tim schrieb:
> wozu braucht es den das valid in der sensitivity list?
Ach Sch......lags kaputt, Kopierfehler...  :-(

Richtig ist es so:
1
process (clk) begin
2
 if rising_edge (clk) then
3
   if altes_valid='1' and valid='0' then
4
     own_valid <= '1';
5
   else
6
     own_valid <= '0';
7
   end if;
8
   altes_valid <= valid;
9
 end if;
10
end process

von tim (Gast)


Lesenswert?

Hallo Lothar
Ich hätte noch eine Frage:
Ich habe mir angewöhnt, das own_valid "default mässig" zu setzen und 
dafür kein else zu verwenden:
1
process (clk) begin
2
 if rising_edge (clk) then
3
   own_valid <= '0'; -- default value
4
   if altes_valid='1' and valid='0' then
5
     own_valid <= '1';
6
   end if;
7
   altes_valid <= valid;
8
 end if;
9
end process

Gibt es gegenüber deinem Beispiel in der Synthese einen unterschied? 
Muss ich mir das abgewöhnen? Funktioniert hat es bis jetzt immer ohne 
Probleme.
Gruss

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


Lesenswert?

Es schenkt sich nichts, ob du es so oder so machst.

von tim (Gast)


Lesenswert?

OK danke!

von Xyz X. (Firma: xyz) (khmweb)


Lesenswert?

tim schrieb:
> Ich habe mir angewöhnt, das own_valid "default mässig" zu setzen und
> dafür kein else zu verwenden

...

> Gibt es gegenüber deinem Beispiel in der Synthese einen unterschied?

Ja:
else beschäftigt immer wieder und kostet mind. Zeit für else und das 
Setzen auf 0. Diese Version hingegen setzt nur einmal auf 0 und einmal 
auf 1. Es gibt also max. nur ein Ereignis, das auf 1 setzt und nur eine 
Anweisung zum Setzen auf 0.

Ich bin zu neu in diesem Bereich, aber bei der Programmierung ist diese 
Version generell die bessere Vorgehensweise, da sie schneller ist. Fällt 
viell. nicht so sehr ins Gewicht, wenn das Ganze nur 1mal geschieht.

Das else dürfte auch zusätzlichen Speicherplatz benötigen...

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


Lesenswert?

War das jetzt Satire?
Es mag sein, dass das Wort "else" Speicherplatz braucht (genau 4 Bytes), 
aber in der Synthese wird im Vergleich mit der Defaultzuweisung eben 
kein Unterschied zu sehen sein.

von Xyz X. (Firma: xyz) (khmweb)


Lesenswert?

@Lothar
Warum sollte es in diesem Forum Satire geben? ;-)
Lieber Lothar, hatte ich vergessen zu erwähnen, dass ich neu in diesem 
Bereich bin?

Bei einem Prozessor kostet die Verarbeitung von unscheinbaren 4 Bytes 
Zeit. Wenn das nicht im CPLD geschieht, hab ich was zugelernt. Ich frag 
mich dann aber, wozu die 4 Bytes dienen.

von Marius W. (mw1987)


Lesenswert?

VHDL ist eine HARDWARE-Beschreibungssprache... Du machst damit also 
Hardware. Dass der else-Zweig Zeit benötigt, ist aber reine 
Software-Denkweise. Und die 4 Bytes, von denen Lothar spricht, ist 
einfach nur der Speicher in der VHDL-Datei. Da kostet ein else natürlich 
4 Bytes.

Gruß
Marius

von Xyz X. (Firma: xyz) (khmweb)


Lesenswert?

Danke Marius für die Aufklärung. Ich hoffe, dass ich bald mehr davon 
versteh.

von Klaus (Gast)


Lesenswert?

Karl-Heinz M. schrieb:
> Lieber Lothar, hatte ich vergessen zu erwähnen, dass ich neu in diesem
> Bereich bin?

Es macht gar nichts, wenn man neu ist und noch nicht den vollen 
Durchblick hat :-) Immer fleißig weiter lernen, dann wird das schon ;) 
Aber: Wenn man keine Ahnung hat, sollte man sich etwas zurückhalten mit 
Tipps an andere, wenn man dabei nur sein nicht vorhandenes Wissen 
verbreitet...

von Xyz X. (Firma: xyz) (khmweb)


Lesenswert?

Ach Klaus, es war doch alles schon gesagt. Hatte doch schon mein Fett 
weg ;-) und mein Wissen an falscher Stelle angebracht. Von Nichtwissen 
verbreiten kann überhaupt keine Rede sein, lies bitte noch mal.

Danke auch für Deine Zuversicht, dass es mit mir schon noch wird. Du 
scheinst mich ja sehr gut zu kennen... :-)

von quarks (Gast)


Lesenswert?

Danke für die zahlreichen Antworten.

Nun möchte ich es doch in wenig anders lösen. Und zwar möchte ich das 
own_valid Signal eine definierte Anzahl an Takten länger aktiv sein 
lassen, als das Eingangssignal valid.

Wenn ich also eine Taktdauer von 25 ns habe und das valid Signal ist 10 
Takte lang, also 250 ns, dann möchte ich beispielsweise das own_valid 
Signal 4 Takte länger aktiv lassen, also dann 350 ns lang.

Mein Gedanke war nun, ein RS-Flip Flop zu bauen, welches bei der 
steigenden Flanke von valid gesetzt wird (own_valid <= '1'). Bei der 
fallenden Flanke von valid soll ein Zähler ausgelöst werden, welcher 
dann die 4 weiteren Takte zählt und danach das RS-Flip Flop auf 0 zurück 
setzt (own_valid <= '0'). So könnte ich innerhalb des Zählers die 
zusätzliche Taktlänge des own_valid Signals variieren.

Wäre das eine sinnvolle Lösung?

Das RS Flip Flop würde ich folgendermaßen aufbauen:
1
process(r,s) 
2
begin
3
  if(s ='1' and r ='0') then
4
  own_valid <= '1'; -- setzen
5
  elsif(s ='0' and r ='1') then -- zurück setzen
6
  own_valid <='0';
7
  elsif(s ='0' and r ='0') then
8
  own_valid <= own_valid; -- speichern
9
  --else own_value <= 'u'; -- undefined
10
  end if;
11
end process;

Das Flip Flop würde ich dann mit der steigenden Flanke des valid Signals 
setzen
1
process (valid)
2
begin
3
  if rising_edge(valid) then  
4
     s <= '1';  
5
  end if;
6
end process;

Ich habe es nur noch nicht hinbekommen, den Zähler bei der fallenden 
Flanke des valid Signals richtig zu erzeugen.
Setze ich dann beispielsweise ein start_count Signal HIGH, wenn die 
fallende flanke des valid Signals kommt, welches dann in einem sepraten 
Prozess den Zähler auslöst?

Ist die Umsetzung denn soweit i.O ?

Vielen Dank !!!

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


Lesenswert?

quarks schrieb:
> Das Flip Flop würde ich dann mit der steigenden Flanke des valid
> Signals setzen
Es gibt (für Anfänger) nur 1 Takt im Design.
Das ist idR. der, der aussen am CLK-Pin angeschlossen ist.

> Ist die Umsetzung denn soweit i.O ?
Vermutlich nicht.


Jetzt sag erst mal, was du machen willst und worauf du es machen willst.
Woher kommt das valid, was soll das own_valid bewirken?


> --else own_value <= 'u'; -- undefined
Schöne theoretische VHDL-Welt...

quarks schrieb:
> Wenn ich also eine Taktdauer von 25 ns habe und das valid Signal ist 10
> Takte lang, also 250 ns, dann möchte ich beispielsweise das own_valid
> Signal 4 Takte länger aktiv lassen, also dann 350 ns lang.
Das würde ich dann so machen:
1
signal cnt : integer range 0 to 4;
2
3
4
process begin
5
   wait until rising_edge(clk25ns);  -- Es kann nur Einen geben!
6
   if (valid='1') then   -- wenn valid kommt
7
     own_valid <= '1';   --   own_valid setzen
8
     cnt <= 0;           --   Zähler zurücksetzen
9
   else                  -- kein valid mehr da
10
     cnt <= cnt+1;       --   zählen
11
     if (cnt=4) then     --   wenn auf 4 gezählt
12
        own_valid <= '0; --      own_valid zurücksetzen   
13
     end if;
14
   end if;
15
end process;

von quarks (Gast)


Lesenswert?

Vielen Dank Lothar, es funktioniert soweit.

Lothar Miller schrieb:
> Jetzt sag erst mal, was du machen willst und worauf du es machen willst.
> Woher kommt das valid, was soll das own_valid bewirken?

Das valid Signal kommt von einem Sensor. Das own_valid Signal geht zu 
einem Treiberbaustein. Dieses muss um 4 Takte länger sein damit, damit 
ich noch zusätzliche Daten anhängen kann.

Alle guten Dinge sind ja bekanntlich drei :-)

Am besten wäre es jedoch, wenn mein own_valid Signal sich aus einer 
ODER-Verknüpfung des valid Signals und des 4clk Signal zusammen setzt.
1
own_valid <= valid or valid_4T

Also so:

|------------10-----------------|  |--------------4-----------|

   |---|   |---|   |---|   |---|   |---|   |---|   |---|   |---|
---|   |---|   |---|   |---|   |---|   |---|   |---|   |---|   |clk25ns

   |---------------------------|
---|                           |--------------------------------- valid

                               |--------------------------------|valid4T
-------------------------------|                                |


   |------------------------------------------------------------|
---| 
|-own_valid


Dadurch kann ich dann besser separieren, sodass meine Daten1 anliegen, 
wenn valid HIGH ist und meine Daten2, wenn valid4T HIGH ist.

Für diese Umsetzung muss ich doch die fallende Taktflanke von valid 
erkennen, sodass das valid4T Signal 'quasi zeitgleich' kommt ?

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


Lesenswert?

quarks schrieb:
> Das valid Signal kommt von einem Sensor.
Und der Takt auch?
Ist das valid synchron zum Takt?

Oder ist es eher so:
Dein externes Signal kommt nicht immmer so hübsch mit dem Takt. Wenn es 
wirklich irgendein Sensor ist, dann hält der sich nicht an den 
FPGA-Takt, sondern hat irgendein eigenes Zeitverhalten und dann kommt 
und geht das valid, wie es will.

quarks schrieb:
> Dieses muss um 4 Takte länger sein damit, damit ich noch zusätzliche
> Daten anhängen kann.
Woran anhängen? Salamitaktik?
Schreib einfach mal mehr von deinem System:
Welches FPGA/CPLD?
Welcher Sensor?
Welche Taktfrequenz(en)?
Was machen die neu dazu gekommenen Daten?
Worauf bezieht sich das valid?

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.