Forum: FPGA, VHDL & Co. VHDL, Taktproblem, LED


von Mario (Gast)


Lesenswert?

Hallo,

als Anfänger habe ich mal eine LED zum Blinken gebracht und zwar mit 
diesem CODE: (takt eingang ist 27 MHZ)


    ----------------- STEUERUNG LED2
    process (clk, reset)

    variable cnt: integer;
    variable led: std_logic;

    begin

    if (clk = '1') and clk'event then
    if reset = '1' then
    cnt:= 0;
    led:= '0';
    elsif (cnt = 27000000) then        -- da 27 MHZ
    cnt := 0;
    led:= not led;
    else
    cnt:= cnt +1;
    end if;
    end if;


    LED2<=led;
    end process;

Mit den Zahler habe ich das auch soweit verstanden und was da gemacht 
hab auch :) Jetzt wollte ich aber das ich die LED für eine 1 sek alle 3 
sekunden blinken lass. Mit dem Code aber geht es nur 3 sek an 3 sekunden 
aus. (entsprechen cnt 27000000 auf 81000000)

ich hab mir überlegt mit der fallenden Flanke wieder runterzählen zu 
lassen, aber weiss nicht wie ich das so bewerkstelligen soll.


Kann mir jemand helfen?


Danke

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


Lesenswert?

Vorab:
In VHDL dürfen am Zeilenanfang Leerzeichen stehen. Das verhilft zu 
deutlich besserem Überblick...

> für eine 1 sek alle 3 sekunden blinken lass
Also 1 sec an, 2 sec aus?
Wie wärs damit:
1
  signal cnt: integer;
2
3
  process (clk) -- reset ist hier unnötig, weil synchron
4
  begin
5
    if (clk = '1') and clk'event then
6
       if reset = '1' then
7
          cnt <= 0;
8
       elsif (cnt = 27000000*3) then        -- da 27 MHZ
9
          cnt <= 0;
10
       else
11
          cnt<= cnt +1;
12
       end if;
13
    end if;
14
  end process;
15
16
  LED2 <= '1' when cnt<27000000 else '0';

BTW:
Als Anfängerregel: vermeide Variable.
Such dazu einfach mal hier im Forum nach
+problem +variabl*
Und du findest z.B. den Beitrag "Beschreibung einer State Machine"

von Mario (Gast)


Lesenswert?

Hi,

super danke für die Antwort, funktionieren tut es auch aber so ganz hab 
ich es nicht verstanden...

-- elsif (cnt = 27000000*3) then
Das heisst er zahlt hier  bis 81MHZ  ?

-- LED2 <= '1' when cnt<27000000 else '0';
Heisst es wenn der takt auf 27 MHZ ist leuchtet die diode ansonsten 0.


Was mir aber aufgefallen ist, das die LED ständig leuchtet, und beim 
Reset anfängt zu blinken, vorher war sie aber aus und hatt erst 
angefangen zu blinken wenn ich reset gedruckt hab?


Gruss

Danke!

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


Lesenswert?

> Was mir aber aufgefallen ist, das die LED ständig leuchtet
Ja, da mußt du mit den Resetwerten und dem Vergleicher noch etwas 
herumspielen ;-)

> Das heisst er zahlt hier  bis 81MHZ  ?
Nein, er zählt auf 3 mal 27Mio, also 3 mal 1 Sekunde.

> Heisst es wenn der takt auf 27 MHZ ist leuchtet die diode ansonsten 0.
Wieder nein.
Solange der Zählerstand kleiner 27Mio ist, wird eine 1 ausgegeben. In 
deinem Fall braucht er für die 27Mio Zählschritte 1 Sekunde.

BTW:
Du machst es der Toolchain leichter, wenn du den Bereich deiner Integer 
einschränkst.
  signal cnt: integer range 0 to 81000000;

von Max (Gast)


Lesenswert?

Hallo Lothar!


Ich bin ebenfalls VHDL-Anfänger und habe eine kurze Verständnisfrage zu 
dem VHDL-Code.
In diesem Code wird von 0 bis (27000000*3) hochgezählt, was bedeutet, 
dass im Ganzen (27000000*3)+1 Takte gezählt werden und nicht 
(27000000*3).
Demnach dauern in dem Beispiel diese 3 Sekunden um genau (1/27000000)s 
länger als es sein sollte.

Ich möchte jetzt nicht als Wichtigtuer abgestempelt werden, bei einer 
Anzeigeblinkled ist das wirklich egal. Es geht mir nur um das eigene 
Verständnis.

Verhält es sich so, wie ich oben geschrieben habe?
Danke im Voraus.


Schöne Grüße

Max

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


Lesenswert?

> Verhält es sich so, wie ich oben geschrieben habe?
Richtig.

Das macht bei 81000000 nicht viel aus (ein Quarz ist ungenauer), aber 
wenns mal ein Teiler durch 10 sein soll, dann sind es gleich 10% 
Unterschied, ob ich von 0 bis 9 zähle oder von 0 bis 10. Korrigiert 
sollte es heissen:
1
signal cnt: integer range 0 to 27000000*3-1;
2
:
3
 elsif (cnt = 27000000*3-1) then
4
    cnt <= 0;
5
:

von Duke Scarring (Gast)


Lesenswert?

@Lothar und andere Fortgeschrittene:

Falls der Zählerendwert (limit) variabel gestaltet wird, verschluckt 
sich bei Xilinx die Synthese manchmal und es wird Unsinn synthetisiert 
:-/
Die Synthese (und die Simulation) läuft problemlos durch, nur das Design 
(und die Netzlistensimulation) funktioniert nicht.
1
signal limit: integer range 0 to 27000000*3-1;
2
signal cnt  : integer range 0 to 27000000*3-1;
3
:
4
 elsif (cnt = limit-1) then -- WARNING: the -1 can cause synthesis errors!
5
    cnt <= 0;
6
:
Das wollte ich nur mal erwähnt haben, damit sich mancher vielleicht ein 
paar Tage Fehlersuche ersparen kann.

Duke

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


Lesenswert?

@Duke Scarring
> Falls der Zählerendwert (limit) variabel gestaltet wird
> verschluckt sich bei Xilinx die Synthese manchmal
Das ist ein unschönes Verhalten... :-/
Hast du dazu noch irgendwelche Rahmenbedingungen?
Variable Zähler-Endwerte sind an sich nicht ungewöhnlich. Hängt es "nur" 
an der Manipulation des Zählerendwertes für den Vergleich (die -1)?
Sowas macht evtl. Probleme:
1
  elsif (cnt = limit-1) then
Sowas aber nicht:
1
  elsif (cnt = limit) then

von Duke Scarring (Gast)


Lesenswert?

@Lothar:
Ja, es hängt nur an der Subtraktion des Zählerendwertes für den 
Vergleich.

Duke

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.