Forum: FPGA, VHDL & Co. Takterzeugung durch zwei Taktflanken


von Der D. (daimlerfahrer)


Lesenswert?

Servus zusammen,

ich versuche derzeit in VHDL folgendes umzusetzen:
Ich benutze zwei zueinander verschobene Takte mit gleicher Frequenz.
Nun möchte ich bei der steigenden Flanke des einen Takts, den Ausgang 
auf High setzen und mit der steigenden Flanke des zweisen Taks 
rücksetzen auf Low. Ziel dieser Anwendung ist eine PWM mit einstellbarem 
Ein- und Ausschaltzeitpunkt.

Leider bekomme ich das ganze in VHDL nicht realisiert. Der Versuch:
1
process (EinschaltFlanke)
2
begin
3
   if (EinschaltTakt'event and EinschaltTakt='0') then 
4
      Ausgang <= '1';
5
   end if;
6
end process;
7
8
process (AusschaltTakt)
9
begin
10
   if (AusschaltTakt'event and AusschaltTakt='0') then 
11
      Ausgang <= '0';
12
   end if;
13
end process;
Ist nicht synthetisierbar, was ich auch verstehe.
Ersetze ich jedoch die zweite Flankenerkennung durch eine Abfrage des 
Zustands (if AusschaltFlanke='1' then...) funktioniert das Ganze auch 
nicht.

Habt ihr Tipps, wie ich aus zwei Takten in oben beschriebener Weise ein 
Signal generieren kann?
Eine einfache AND Verknüpfung hatte ich schon angedacht, aber auf die 
beiden Flanken wäre bei meinen Eingangssignalen deutlich besser.

Danke und Grüße

von Nephilim (Gast)


Lesenswert?

warum benutzt die beiden signale nicht als Reset und Enable und machst 
alles in einem Prozess. damit sollte das doch dann deine funktionalität 
ergeben oder ?

von Der D. (daimlerfahrer)


Lesenswert?

Klar, das geht. Die Frage war jedoch, ob man nicht auf zwei 
unterschiedliche Taktflanken ein- und ausschalten kann.
Der grund hierfür ist einfach: meine Flanken sind sauber, die Signale 
schrecklich :P

von Klaus F. (kfalser)


Lesenswert?

Abgesehen davon, dass Dein Programm nicht synthetisierbar ist, ist Dein 
Problem wahrscheinlich, dass Du das Signal gleichzeitig aus 2 Prozessen 
veränderst.
Das wirkt in VHDL wie ein Bus-Signal, das von 2 Signalen getrieben wird.
Signale sind in VHDL eben keine Variablen, die man an einer Stelle 
setzen und an der anderen Stelle löschen kann.

Schreibe alles in einen Prozess, z.B.

process (EinschaltFlanke, AusschaltTakt)
begin
   if (EinschaltTakt'event and EinschaltTakt='0') then
      Ausgang <= '1';
   end if;
   if (AusschaltTakt'event and AusschaltTakt='0') then
      Ausgang <= '0';
   end if;
end process;

dann klappt's.
Das dies auch nicht synthetisierbar ist, ist wohl klar, oder?

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


Lesenswert?

> Habt ihr Tipps, wie ich aus zwei Takten in oben beschriebener Weise ein
> Signal generieren kann?
Wozu (um alles in der welt) brauchst du für 1 PWM gleich 2 Takte?

Also ich für meinen Teil mach PWMs immer so:
1
process begin
2
  wait until rising_edg(clk);
3
  pwmcnt <= pwmcnt+1;
4
  if(pwmcnt = zaehlergrenze) then
5
    pwmcnt <= 0;
6
    ausgang <= '0';
7
  end if;
8
  if(pwmcnt = pwmwert) then
9
    ausgang <= '1';
10
  end if;
11
end process;

zaehlergrenze bestimmt die PWM-Frequenz
pwmwert bestimmt den Übergang von 1 nach 0

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


Lesenswert?

Oder alternativ, falls der FPGA-Takt zu hoch wäre (z.B. 50MHz)
mit Prescaler für die PWM-Frequenz:
1
process begin
2
  wait until rising_edg(clk);         -- z.B. 50MHz
3
  prescaler <= prescaler+1;  
4
  if (prescaler=vorteilerwert) then   -- vorteilerwert z.B. 499 für PWM-Zählerfrequenz von 100kHz (50MHz/500)
5
    prescaler <= 0;
6
    pwmcnt <= pwmcnt+1;
7
    if (pwmcnt = zaehlergrenze) then  -- zaehlergrenze z.B. 999 für PWM-Frequenz (Zyklus) vom 100Hz (100Khz/1000)
8
      pwmcnt <= 0;
9
      ausgang <= '0';
10
    end if;
11
    if (pwmcnt = pwmwert) then        -- auflösung 1000 Schritte 
12
      ausgang <= '1';
13
    end if;
14
    if (pwmwert = 0) then             -- Grenzfall
15
      ausgang <= '0';
16
    end if;
17
  end if;   
18
end process;

von Der D. (daimlerfahrer)


Lesenswert?

Lothar Miller wrote:
> Wozu (um alles in der welt) brauchst du für 1 PWM gleich 2 Takte?

Ganz einfach - ich möchte den bestehenden Takt von 13,56 MHz beibehalten 
und benötige eine einstellbarkeit von 500 ps. Das lässt sich einfach 
nicht (günstig) über einen Zähler lösen. Also verschiebe ich zwei 
Signale gegeneinander und kombiniere diese wieder zu meinem 
Ausgangssignal mit geänderter Pulsbreite und einstellbarem Ein- und 
Ausschaltzeitpunkt.

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


Lesenswert?

> Ganz einfach...
> ...einstellbarkeit von 500 ps
Na gut, einfach ist anders. Da wird dir ein kombinatorisches 
Zusammenfassen nicht erspart bleiben. Was ist denn eigentlich deine 
Zielplattform? Solange braucht ja schon eine LUT im FPGA, bis das 
Ergebnis am Ausgang stabil ist.

> einstellbarkeit von 500 ps.
> Das lässt sich einfach nicht (günstig) über einen Zähler lösen.
Ja, der muss dann schon arg schnell sein. 2 GHz sind wohl nur mit einem 
ASIC drin ;-)

von Klaus F. (kfalser)


Lesenswert?

Auf welche Art werden denn Deine Takte gegeneinander verschoben?
Mit der DCM ?

von Der D. (daimlerfahrer)


Lesenswert?

>Auf welche Art werden denn Deine Takte gegeneinander verschoben?
über digital einstellbare Delay-Lines
DCM ist sicher auch eine Möglichkeit, jedoch ist hier kein fester Wert 
direkt schaltbar (zumindest beim variablen Phaseshift nicht), sondern 
die Phase wird Schritt für Schritt geändert, bis zum gewünschten Wert.

von Joko (Gast)


Angehängte Dateien:

Lesenswert?

Hilft angehängtes vhd-schnipsel als Ansatz ?

Ist die Nachbildung eines DDR-Flip-Flops in Slices...
(Wäre natürlich noch entsprechend Deines 2. Taktes umzubauen)

Hier wird die Funktion dadurch gewährleistet, daß "rising" und
"falling" edge immer "weit genug" entfernt sind - was Du bei
Deinen Takten noch sicherstellen mußt! Daher ist obige Frage
berechtigt (nur hier anders gestellt): "wird der 2. Takt
aus dem ersten erzeugt ?"

/Jochen

von Der D. (daimlerfahrer)


Lesenswert?

Danke für den Codeschnipsel Jochen! Damit funktioniert es schonmal. 
Prima.

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.