www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Abschließen der Schleife trotz Interrupt!


Autor: Chris K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Community,

ich setze mich gerade mit den Grundlagen von VHDL auseinander und bin 
bei meinen Programm auf ein Problem gestoßen, wofür ich leider keine 
Lösung finde, bestimmt ihr aber ;)

In meinem Programm werden jeweils 3 LEDS per while-Schleife angesteuert, 
welche hintereiander eingeschaltet und zum Schluß zusammen ausgeschaltet 
werden. Es funktioniert quasi wie ein Blinker nach rechts und nach 
links.
So der Interrupt ist der Schalter, der die Blinkrichtung ändert. Die 
Anforderung ist aber folgende, dass der angefangene Blinkzyklus 
abgeschlossen wird, d.h. wenn ich gerade bei der zweiten LED links bin 
und ich den Schalter umstelle, soll der "Links-Blink-Zyklus" noch 
abgeschlossen werden, bevor der andere Zyklus beginnt.

Oder in Kurzform: Wie erzwinge ich, dass die while Schleife 
abgeschlossen wird. Ich meine bei C ist das realtiv einfach möglich, 
aber ich weiß, wir sind hier nicht bei C.

Vielen Dank schonmal für eure Hilfe!

Chris

Autor: Nobody (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Poste mal Deinen Code.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine While-Schleife in Hardware? Cool  :-o
Lass mal deinen Code sehen.

> In meinem Programm werden jeweils 3 LEDS per while-Schleife angesteuert,
Glaub mir: wenn du Hardware mit VHDL beschreibst, dann hast du weder ein 
Programm noch eine while-Schleife.

Autor: Julian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könntest du das nicht mit nem endlichen Automaten (bei Fragezeichen im 
Gesicht hilft Wikipedia o.Ä.) machen, der nur im Anfangszustand den 
Taster (Status in FlipFlop gespeichert) abfragt?

Autor: Nobody (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jedenfalls wäre ein "while" selbst wenn es richtig angewandt wird nicht 
synthetisierbar. Also höchsten für Testbenches etc. gut. Es dient 
hauptsächlich dazu eine im vorhinein bekannte Anzahl gleichartiger 
Strukturen zu beschreiben.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Könntest du das nicht mit nem endlichen Automaten machen...
Sollte das heißen:
Könntest du nicht endlich nen Automaten machen... ;-)

Kurz und gut:
Schlicht und einfach Alles, was in Hardware (FPGA und CPLD) 
nacheinander abläuft, wird auf so einen Automaten abgebildet werden 
müssen.

Autor: Rene B. (themason) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vor allem ... einen Interrupt ? In VHDL ?!
Wie soll das denn gehen ?

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rene Böllhoff schrieb:
> Vor allem ... einen Interrupt ? In VHDL ?!
> Wie soll das denn gehen ?

Indem man einen Programmable Interrupt Controller synthetisiert? ;-)

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Einen PIC?  Buoäh...  ;-)

Autor: Rene B. (themason) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Indem man einen Programmable Interrupt Controller synthetisiert? ;-)

Öhm ja ... so gehts natürlich auch. Fehlt nur noch der Rest vom 
Prozessor. Aber wie Lothar schon meinte : Is ja eh nen PIC
duckundwech

Autor: faustian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn es um irgendeine Form von CPU geht, ist das Stichwort 
Interruptmaskierung.

Autor: Chris K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es tut mir Leid für die jenigen, die Ihr Wissen zur Show stellen wollen, 
ich bin wie gesagt am Anfang von VHDL. Mit Interrupt meine ich einfach, 
eine Unterbrechung, was man ja aus meinen Text erschließen kann.

Und warum soll man keine "while loop" in einem prozess verwenden können? 
Bei klappt es aufjedenfall.

Hier der Code, für die Menschen, die einen wirklich helfen möchten:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
Use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;




entity Main is
  Port(
  clk: in std_logic ;               Schalter: in bit;
  LED: out std_logic_vector (5 downto 0));


end Main;

architecture Behavioral of Main is

signal led_intern: std_logic_vector (5 downto 0);
signal counter: std_logic_vector (25 downto 0);

begin

process (clk,Schalter,counter)

begin


if (rising_edge(clk)) then

counter <= counter + "01";

end if;


while Schalter = '1' loop

case counter(25 downto 24) is

          when "00" => led_intern <= "001000";
    when "01" => led_intern <= "011000";
    when "10" => led_intern <= "111000";
    when others => led_intern <= "000000";

end case;

end loop;


while not Schalter ='1' loop

case counter(25 downto 24) is

    when "00" => led_intern <= "000100";
    when "01" => led_intern <= "000110";
    when "10" => led_intern <= "000111";
    when others => led_intern <= "000000";

end case;



end loop;



end process;


LED <= led_intern;


end Behavioral;

Autor: Chris K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso und das ganze hat nix mit ner CPU zu tun , sondern passiert auf 
dem XILINX Spartan 3 Board ;)

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Bei klappt es aufjedenfall.
Ja, was klappt denn?
Hast du das Synthetisiert?
Welche Warnungen hast du bekommen (Latch, kombinatorial Loop)?
Hast du dir den RTL-Schaltplan dazu schon mal angesehen?
Funktioniert das in realer Hardware?
Oder nur im Simulator?

> Es tut mir Leid für die jenigen, die Ihr Wissen zur Show stellen wollen,
> ich bin wie gesagt am Anfang von VHDL.
Jetzt sei doch nicht gleich so angesäuert... :-/
Sieh dir mal meine Lauflichtvarianten an. Eine davon ist garantiert 
total simpel auf deinen Anspruch abänderbar: 
http://www.lothar-miller.de/s9y/archives/61-Lauflicht.html

Autor: Chris K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Lothar: Ja tut mir Leid, wir müssen uns das ganze in recht kurzer Zeit 
für das Testat auf den Schirm bringen und da ist man schonmal etwas 
schneller genervt, wenn man sieht, was man noch alles zu tun hat ;)

Die Synthese ergibt weder Fehler noch Warnungen, die habe ich alles 
behoben. Die Schaltung funktioniert auch wie sie soll. Das einzige 
Problem besteht darin, dass wenn man den Schalter umschaltet, die Leds 
sofort wechseln, sprich der eine Zyklus wird nicht beendet, was aber 
eine der Vorgaben ist.

Verstehst du mein Problem? ;)

Autor: Rene B. (themason) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nimm die Witzelei nicht persönlich.
Es ist so das die meisten die Vorstellung haben das VHDL ein 
Programmablauf ist, bzw das man "normal" programmieren kann.
VHDL ist jedoch keine Programmiersprache sondern eine 
Beschreibungssprache. Du beshreibst das Verhalten deiner Hardware.
Die Hardware ist aber parallel, d.h. was du beschreibst läuft parallel 
ab und nicht sequentiell. Sequentielle Teile kann man zwar schon 
schreiben, aber diese sind dann eher für die Simulation als sogenannte 
Stimuli zum Testen deines Designs, aber eben nicht geeignet für die 
Synthese (sprich die Implementation auf dem FPGA selbst).
Wenn man sequentielles Verhalten haben will, so benötigt man entweder 
einen Zähler oder eine Statemachine. Nur damit lassen sich überhaupt 
erst Abläufe realisieren.
Und so gesehen macht eine Unterbrechung (eben der besagte Interrupt) bei 
parallel laufender Hardware keinen Sinn ;-P. Ist dann halt nur was 
schwierig zu verstehen was du meinst :-). Nimms nicht übel :-)

Zu deinem Problem

Wie besagt machen Schleifen in Hardware keinen Sinn.
Für dein Problem reicht eigentlich der Zähler aus.
Die Abfrage auf die Blinkrichtung kann man über ein if machen indem 
beide cases enthalten sind, die also theoretisch immer SOFORT 
umschalten.
Das if bezieht sich dann aber nicht auf die Schalterstellung, sondern 
ein weiteres Signal das den Schalterzustand übernimmt wenn der 
Blinkzyklus zuende ist.
Das wäre ein Lösungsvorschlag.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine loop lässt sich ganz leicht auch als if-Abfrage beschreiben.
Man macht keine kombinatorisch getakteten Prozesse. Besser: Aufteilen.
signal richtung : std_logic;
process (clk)
begin
  if (rising_edge(clk)) then
    counter <= counter + "01";
    if counter(25 downto 24)="00" then -- nur bei diesem Zählerzustand die Richtung ändern
      richtung <= Schalter;            -- Richtung soll gespeichert werden, deshalb im getakteten Prozess
    end if;
  end if;
end process;

process (richtung ,counter)
  if richtung = '1' then
    case counter(25 downto 24) is
    when "00"   => led_intern <= "001000";
    when "01"   => led_intern <= "011000";
    when "10"   => led_intern <= "111000";
    when others => led_intern <= "000000";
    end case;
  else
    case counter(25 downto 24) is
    when "00"   => led_intern <= "000100";
    when "01"   => led_intern <= "000110";
    when "10"   => led_intern <= "000111";
    when others => led_intern <= "000000";
    end case;
  end if;
end process;

Autor: Chris K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Lothar:

Vielen Dank für diese Antwort und deine Tipps! Es funktioniert alles 
genau so, wie es sein soll und man hat dabei noch was gelernt! ;)

Autor: Chris K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Frage noch Lothar, wegen dem Speichern der Richtung im getakteten 
Prozess. Ist es besser dort platziert oder MUSS es dort platziert sein? 
Und warum?

Danke für die Antwort im Vorraus ;)

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> wegen dem Speichern der Richtung im getakteten Prozess.
Grundsätzlich Alles, was gespeichert werden soll, muß getaktet sein. 
Denn (grob gesagt) die einzigen Speicherglieder im FPGA sind Flipflops. 
Und das sind getaktete Bauteile.

Ein nicht getaktetes Speichergleid ist ein Latch, und das wirst du 
garantiert nur in sehr ausgewählten Fällen wirklich wollen...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.