mikrocontroller.net

Forum: FPGA, VHDL & Co. VHDL Prozess nur "anstupsen"


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Mark W. (kram) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich baue mir gerade einen Prozess, womit ich einen 
Initialisierungsvorgang realisieren moechte.
Nun weiss ich nicht, wie ich den Prozess kontrolliert starten kann. Ich 
moechte, dass er bei einer Flanke anlaeuft und einmal durchlaeft und 
dann stehen bleibt. Ich frage mich ob ich das in dem Prozess realisieren 
kann, oder ob ich eine externe Schalung benoetige, die mir aus eine 
Flanke ein Dauersignal generiert und das dann als Enable verwendet wird. 
Was passieren soll wenn die Flanke waerend des Prozesses kommt, ist 
erstmal egal, kann neu anlaufen oder auch ignoriert werden waerend der 
Laufzeit des Prozesses.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity TESTPROCESS is
  port(  CLK, RST : in std_logic;
      Y   : out std_logic;
      Z   : out std_logic
  );
end TESTPROCESS;

architecture BEHAVIORAL of TESTPROCESS is

signal c : integer :=0;
constant t1 : integer :=0;
constant t2 : integer :=10;
constant t3 : integer :=20;
constant t4 : integer :=30;

begin

process(CLK)
begin
  if(rising_edge(CLK)) then
    if c = t1 then
      Y <= '0';
      Z <= '0';
    elsif c = t2 then
      Y <= '0';
      Z <= '1';
    elsif c = t3 then
      Y <= '1';
      Z <= '0';
    elsif c = t4 then
      Y <= '1';
      Z <= '1';
    end if;
    if c < 200 then
    c <= c+1;
    end if;
  end if;
end process;

end BEHAVIORAL;

Autor: Lothar M. (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mark W. schrieb:
> Nun weiss ich nicht, wie ich den Prozess kontrolliert starten kann. Ich
> moechte, dass er bei einer Flanke anlaeuft und einmal durchlaeft und
> dann stehen bleibt.
Du denkst zu sehr wie ein "Softwareprogrammierer" (auch die Beschreibung 
in diesem Prozess sieht ganz danach aus...)
Ein "Prozess" in VHDL beschreibt eine Hardware, die in LUTs und 
Flipflops realisiert wird und immer da ist. Die FSM, die deine 
Beschreibung darstellt, wird nach dem Laden des FPGAs, bei dem der 
Zähler sowie wahrscheinlich auch X und Y mit 0 initialisert werden (das 
darf der Synthesizer laut deiner Beschreibung aber handhaben wie er 
will, denn du definierst X und Y erst ab dem 11. Takt). Dann zählt der 
Zähler mit jedem Takt eins hoch und die  Vergleicher lösen bei 
bestimmten Zählerständen bestimmte Aktionen aus. Ab dem 31. Takt bleiben 
X und Y dann auf '1' stehen.

> waerend der Laufzeit des Prozesses.
Die "Laufzeit" eines Prozesses (also ab Aktivierung durch eine 
Signaländerung in der Sensitivliste) ist theoretisch 0. In der Praxis 
kommt der Takt, dann herrscht Hektik in der Logik, die rechtzeitig vor 
dem nächsten Tkat beendet sein muss.

> Was passieren soll wenn die Flanke waerend des Prozesses kommt
Weil die Laufzeit des Prozesses 0 ist (die simulationszeit bleibt 
einfach stehen), kann keine zweite Flanke während der Berechnung des 
Prozesses auftreten...


BTW: was hat die gepostete Code Beschreibung eigentlich mit deiner 
Aufgabe zu tun?

Autor: Mark W. (kram) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lothar M. schrieb:
>
> BTW: was hat die gepostete Code Beschreibung eigentlich mit deiner
> Aufgabe zu tun?
Das ist ein Prototyp meiner Ablaufsteuerung. :-)
Funktioniert auch schon halbwegs. Ich moechte verschiedene Signale 
setzen um andere Hardware zu initialisieren.
Also:
Enable Signale setzen
Reset Signale setzen
Addressdaten setzen
usw.
Und das in einer bestimmten zeitlichen Abfolge. Deswegen der 
Zaehlprozess. Es genuegt wenn ich die Zahlstufen als Taktzyklen 
bestimme, denn ich weiss immer wan ich welche Signale setzen muss. Das 
muss einmal bei einem Tastendruck durchlaufen und stehen bleiben.

Autor: Lothar M. (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mark W. schrieb:
> Und das in einer bestimmten zeitlichen Abfolge.
Ich würde das anders machen. Mit einer FSM und einem Zähler/Timer, der 
für den jeweils nächsten Zustand neu geladen wird. Den Zuständen in der 
FSM kann man sprechende Namen geben und muss nicht mit "Magic Numbers" 
herumhantieren.

Denn dann könnte ich neben dem stupiden geradlinigen zeitlichen Ablauf 
auch leicht eine Reaktion auf ein anderes z.B. von aussen kommendes 
Signal (z.B. ein Endschalter) in diese FSM einbauen. So könnte ich ganz 
leicht in den Ablauf des Kaffeeautomaten mit der Beschreibung FSM0b aus 
dem Beitrag "Re: Hilfe für Code - VHDL" eine Wartezeit 
einbauen.

Oder ich kann mit dieser FSM ganz einfach eine Zeit mittendrin um 5 
Takte verlängern, ohne alle nachfolgenden Zeiten entsprechend anpassen 
zu müssen...

Autor: wendelsberg (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mark W. schrieb:

> Also:
> Enable Signale setzen
> Reset Signale setzen
> Addressdaten setzen
> usw.
>
Warum tut man sich das an, das mit Logik machen zu wollen? Zeitkritisch, 
sehr schnell oder was fuer Gruende sprechen dafuer?

wendelsberg

Autor: Mark W. (kram) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wendelsberg schrieb:
> Mark W. schrieb:
>
>> Also:
>> Enable Signale setzen
>> Reset Signale setzen
>> Addressdaten setzen
>> usw.
>>
> Warum tut man sich das an, das mit Logik machen zu wollen? Zeitkritisch,
> sehr schnell oder was fuer Gruende sprechen dafuer?

Naja, ich habe mir erst ueberlegt eine CPU oder sowas zu nehemn, aber 
das habe ich dann schnell aufgegeben, ist vermutlich ovekill.
Dann habe ich es mit einer FSM gemacht, hat auch funktioniert.
Dann habe ich mir gedacht, man kann die "case when" ja auch rausnehemn 
um die Sache zu vereinfachen.
Jetzt will ich nur noch den Startimpuls einbauen und nach einmaligem 
Durchlaufen zuruecksetzen.
Wenn das nicht klappt, gehe ich wieder zurueck zur FSM.

Autor: Mampf F. (mampf) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mark W. schrieb:
> Nun weiss ich nicht, wie ich den Prozess kontrolliert starten kann. Ich
> moechte, dass er bei einer Flanke anlaeuft und einmal durchlaeft und
> dann stehen bleibt.
-- läuft einmal, bleibt dann stehen
process(clk)
variable state : integer range 0 to 2 := 0; -- default 0
begin
  if rising_edge(clk) then
    if reset='1' then
      -- irgendwas resetten falls notwendig
      state:=0;
    else
      case state is
        when 0 =>
          if trigger='1' then
            state:=1;
          end if;
        when 1 =>
          -- einmalig irgendwas machen
          state:= 2;
        when 2 =>
          -- bleibt für immer in 2
        when others =>
          state:=0;
      end case;
    end if;
  end if;
end if;

oder sowas:
-- läuft einmal, bleibt dann stehen
process(clk)
variable flag : std_logic := '0';
begin
  if rising_edge(clk) then
    if reset='1' then
      -- irgendwas resetten falls notwendig
      flag:='0';
    else
      if trigger='1' and flag='0' then
        -- einmalig irgendwas machen
        flag:='1';
      end if;
    end if;
  end if;
end if;

Die erste Version ist halt eine Statemachine - muss man entscheiden, 
welche Variante man eher braucht.

du kannst statt Variablen auch Signale verwendet - Variablen werden ja 
von Leuten, die damit nicht umgehen können, verteufelt ;-)

: Bearbeitet durch User
Autor: Lothar M. (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mampf F. schrieb:
> Variablen werden ja von Leuten, die damit nicht umgehen können,
> verteufelt ;-)
Ich nehme gerne Variablen. Nur Anfänger fallen damit gern auf die Nase, 
weil sich diese Variable eben wie eine VHDL-Variable, und somit nicht 
wie von ihnen erwartet verhält... 😉

: Bearbeitet durch Moderator
Autor: Mark W. (kram) Benutzerseite
Datum:
Angehängte Dateien:
  • preview image for wf.PNG
    wf.PNG
    2,59 KB, 19 Downloads

Bewertung
0 lesenswert
nicht lesenswert
Ich habe jetzt eine SM genommen und bin jetzt soweit, dass es 
funktioniert wie ich mir das vorgestellt habe. Jedenfalls in der 
Simulation erstmal.
Alles States werden durchlaufen und in der letzten State wird auf das 
Startsignal gewartet.
Wenn das kommt, geht es wieder von vorne los.

Autor: Mampf F. (mampf) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lothar M. schrieb:
> Mampf F. schrieb:
>> Variablen werden ja von Leuten, die damit nicht umgehen können,
>> verteufelt ;-)
> Ich nehme gerne Variablen. Nur Anfänger fallen damit gern auf die Nase,
> weil sich diese Variable eben wie eine VHDL-Variable, und somit nicht
> wie von ihnen erwartet verhält... 😉

Ach und weil man sich - bei suboptimaler Verwendung - recht schnell das 
Timing kaputt machen kann, weil man zuviel in einen Clock-Cycle packen 
kann^^ :)

Autor: Mark W. (kram) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mampf F. schrieb:
> Lothar M. schrieb:
>> Mampf F. schrieb:
>>> Variablen werden ja von Leuten, die damit nicht umgehen können,
>>> verteufelt ;-)
>> Ich nehme gerne Variablen. Nur Anfänger fallen damit gern auf die Nase,
>> weil sich diese Variable eben wie eine VHDL-Variable, und somit nicht
>> wie von ihnen erwartet verhält... 😉
>
> Ach und weil man sich - bei suboptimaler Verwendung - recht schnell das
> Timing kaputt machen kann, weil man zuviel in einen Clock-Cycle packen
> kann^^ :)
Danke fuer Eure Tips, werde mit Variablen vorsichtig umgehen. :-)

VHDL soll ja eine Sprache fuer Hardware sein, dafuer sind die Elemente 
aber sehr an Software angelehnt.
Beispiel: Process
Ein Prozess ist ja gerade etwas, was T>0 braucht, sonst waere es ja kein 
Prozess. Man haette vielleicht unit oder design unit fuer parallele 
Ausfuehrung nehmen koennen und process fuer zeitliche Abfolgen.

Autor: Lothar M. (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mark W. schrieb:
> dass es funktioniert wie ich mir das vorgestellt habe.
Mir erscheint das Handling des Zählers jetzt unnötig umständlich. Warum 
muss der immer mal wieder zwischendurch anhalten, wenn der Zustand 
weitergeschaltet wird? Damit hast du wieder blitzartig so einen 
"Off-Bay-One" Effekt an der Backe (die Zustände werden jetzt jeweils für 
11 Takte gehalten, obwohl die Zahlen 10,20,30 etwas anderes vermuten 
lassen...).

Mein Ansatz wäre so:
:
:
signal c : integer range 0 to 9 := 9;
type state_type is (Idle, S1, S2, S3);
signal state : state_type := S1;

begin

process(CLK) -- nur CLK relevant
begin
  if rising_edge(CLK) then
    if c>0 then
      c <= c-1;
    end if;
    case next_state is
      when Idle =>
        if c=0 and ST='1' then
          next_state <= S1;
          Y <= '0';
          Z <= '0';
          c <= 9;
        end if;
      when S1 =>
        if c=0 then
          next_state <= S2;
          Y <= '0';
          Z <= '1';
          c <= 9;
        end if;
      when S2 =>
        if c=0 then
          next_state <= S3;
          Y <= '1';
          Z <= '0';
          c <= 9;
        end if;
      when S3 =>
        if c=0 then
          next_state <= Idle;
          Y <= '1';
          Z <= '1';
          c <= 9;
        end if;
    end case;
  end if;
end process;
:
:

Und dann gäbe es noch die von mir bevorzugte Variante, die einfach einen 
Zähler hochzählt und über den Index die Werte abbildet:
:
:
signal c  : integer range 0 to 9 := 9; -- bei Integern immer den Bereich angeben, sonst kann der Simulator bei einem Überlauf nicht meckern
signal ci : integer range 0 to 3 := 0;
type pattern_t is array (0 to 3) of std_logic_vector(1 downto 0); 
signal pattern : pattern_t := ("00","01","10","11");

begin

  process begin
    wait until rising_edge(CLK);
    if c>0 then 
      c <= c-1;
    else
      if ci<3 then       -- Index hochzählen
        ci <= ci+1;
        c  <= 9;
      elsif ST='1' then  -- auf Index 3 warten bis Neustart
        ci <= 0;
        c  <= 9;
      end if;
    end if;
  end process;

  X <= pattern(ci)(0);
  Y <= pattern(ci)(1);
:
:

Wenn man da unterschiedliche Zeiten für die einzelnen Zyklen will, dann 
kann man das mit einem zweiten Array erschlagen:
:
:
signal c  : integer range 0 to 9 := 9; -- bei Integern immer den Bereich angeben, sonst kann der Simulator bei einem Überlauf nicht meckern
signal ci : integer range 0 to 3 := 0;
type pattern_t is array (0 to 3) of std_logic_vector(1 downto 0); 
type delay_t is array (0 to 3) of ingeger range 0 to 9;

signal pattern : pattern_t := ("00","01","10","11");
signal delay   : delay_t :=   (  10,   5,   7,   4);

begin

  process begin
    wait until rising_edge(CLK);
    if c>0 then 
      c <= c-1;
    else
      if ci<3 then       -- Index hochzählen
        c  <= delay(ci+1)-1;
        ci <= ci+1;
      elsif ST='1' then  -- bei Index 3 warten bis Neustart
        c  <= delay(0)-1;
        ci <= 0;
      end if;
    end if;
  end process;

  X <= pattern(ci)(0);
  Y <= pattern(ci)(1);
:
:

Mark W. schrieb:
> VHDL soll ja eine Sprache fuer Hardware sein
VHDL ist eine Hardware-Beschreibungs-Sprache.

> dafuer sind die Elemente aber sehr an Software angelehnt.
Nur für den, der vorher Software gemacht hat.

> Beispiel: Process
> Ein Prozess ist ja gerade etwas, was T>0 braucht, sonst waere es ja kein
> Prozess.
??? Mir erschließt sich die Logik nicht...

Die Anweisungen in einem Prozess werden vom simulator per Definition 
in der Zeit 0 berechnet. Denn das Hauptproblem von 
Softwareprogrammierern ist, zu meinen, ein Prozess würde wie ein 
Programm Schritt für Schritt "durchlaufen" und "abgearbeitet". Dem ist 
aber nicht so.

> Man haette vielleicht unit oder design unit fuer parallele
> Ausfuehrung nehmen koennen und process fuer zeitliche Abfolgen.
Es gibt keine zeitlichen Abfolgen. Jeder zeitliche Ablauf muss in einen 
Zustandsautomaten gepackt werden. Und dann gibt es einen Takt, der dafür 
sorgt, dass der Zustandsautomat weitergeschaltet wird (auch ein simpler 
Zähler für ein Delay ist ein Zustandsautomat).
Und jeder Zustand des Prozesses samt nachgeschalteter Logik ist 
"parallel" auf dem FPGA vorhanden. Nur eben ggfs. nicht aktiv. Insofern 
ist diese Unterscheidung "parallele Hardware" und "zeitlicher Ablauf" 
nur in deinem Kopf. Im FPGA sind das alles nur LUTs und Flipflops. Mehr 
"Bauteile" hast du für deine Hardware-Beschreibung nicht zur 
Verfügung...

: Bearbeitet durch Moderator
Autor: Mark W. (kram) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lothar M. schrieb:
...
Die Zahlen 10, 20, 30 sind nur beispielhaft, genau wie die Ausgaenge Y 
und Z, um die Sache gering und einfach zu halten. Sie sollten aber 
variabel einstellbar sein.

Danke fuer das Beispiel, ich werde es mir mal ansehen und ausprobieren.

Autor: Mark W. (kram) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lothar M. schrieb:

>> Beispiel: Process
>> Ein Prozess ist ja gerade etwas, was T>0 braucht, sonst waere es ja kein
>> Prozess.
> ??? Mir erschließt sich die Logik nicht...

Meinem Verstaendniss nach ist eine Prozess eine zeitliche Abfolge von 
Schritten. Ich brauchte einen Prozess, eine Art Ablaufsteuerung, 
aehnlich wie bei einer SPS oder Aehnlichem.
Also genau das was eine FSM macht mit Hilfe des Taktes und Bedingungen.
Zuerst tue dies, dann jenes und zum Schluss warte...
So langsam erschliesst es sich mir, aber nur sehr langsam. :-)

Autor: Lothar M. (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mark W. schrieb:
> Meinem Verstaendniss nach ist eine Prozess eine zeitliche Abfolge von
> Schritten. Ich brauchte einen Prozess, eine Art Ablaufsteuerung,
> aehnlich wie bei einer SPS oder Aehnlichem.
Du darfst nicht versuchen, allgemeine Begriffe aus irgendwelchen anderen 
Welten (SPS oder ähmlichen) auf ein völlig neues Tätigkeitsfeld 
(Hardwarebeschreibung) zu übertragen.

Mark W. schrieb:
> Ich brauchte einen Prozess, eine Art Ablaufsteuerung, aehnlich wie bei
> einer SPS oder Aehnlichem.
Abläufe werden mit FSM gesteuert. Auch in der SPS. Nur heißen die dort 
"Schrittketten", die Zustände werden mit "Merkern" abgebildet usw. usf.

Autor: Mampf F. (mampf) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mark W. schrieb:
> Meinem Verstaendniss nach ist eine Prozess eine zeitliche Abfolge von
> Schritten. Ich brauchte einen Prozess, eine Art Ablaufsteuerung,
> aehnlich wie bei einer SPS oder Aehnlichem.
> Also genau das was eine FSM macht mit Hilfe des Taktes und Bedingungen.
> Zuerst tue dies, dann jenes und zum Schluss warte...
> So langsam erschliesst es sich mir, aber nur sehr langsam. :-)

Nope ...

Es gibt auch kombinatorische Prozesse:
process(a, b)
begin
  c <= a and b;
end process;

das wird einfach in eine und-Verknüpfung umgesetzt.

genauso ginge auch
c <= a and b;

Prozesse können eine andere Syntax nutzen, aber die gleiche Hardware 
erzeugen.

Beispiel:
-- klar, ist ein trivial-beispiel^^
c <= '1' when a='0' else '0';

process(a)
begin
  if a='0' then
    c <= '1';
  else
    c <= '0';
  end if;
end process;

if-then-else oder case funktionieren nur in Prozessen zB.

zu 99% verwende ich Prozesse nur für getaktete Logik ´ala
process(clk)
begin
  if rising_edge(clk) then
    if reset='1' then
      ...
    else
      ...
    end if;
  end if;
end process;

und zu 99.99999999% nur 'clk' in der Sensitivity-List der Prozesse (löst 
schonmal viele Probleme^^).

Kombinatorisches Zeugs ohne Prozess - außer die anderen 
Syntax-Möglichkeiten bringen mir Vorteile. Das ist aber eher selten der 
Fall.

Beispiel hier:
    process(curl_mid_state_low, curl_mid_state_high)
    begin
        for I in 0 to HASH_LENGTH-1 loop
            curl_hash((I*2)/32)((I*2) mod 32) <= curl_mid_state_low(I);
            curl_hash((I*2)/32)((I*2) mod 32 + 1) <= curl_mid_state_high(I);
        end loop;            
    end process;

Da ist ein Prozess für das 'for-loop' schön ... Ginge mit 'generate' 
auch ohne ... aber mei, Geschmackssache^^

Das ist eigentlich so der Brain-F**k, den man bei VHDL nie so wirklich 
los bekommt ... welche Syntax sind innerhalb Prozesse erlaubt, welche 
Außerhalb xD

: Bearbeitet durch User

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.

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