Kombinatorik und Takt trennen?

Gast #4605161
Lesenswert?

Moin,
letztens hatte ich eine Diskussion über VHDL-Beschreibungsarten. Ich 
habe mir VHDL selber beigebracht, der andere hat es im Studium gelernt.
Darf man getaktete Zuweisung und Kombinatorik mischen oder sollte das in 
zwei Prozessen getrennt sein.
Ein Beispiel habe ich hier anhand eines einfachen Zählers, der ständig 
bis zum Maximalwert hochzählt und dann wieder bei 0 anfängt.
Ich würde das in einen Prozess schreiben
1
entity Gemeinsam is
2
    port(
3
        clk     : in std_ulogic;
4
        reset   : in std_ulogic;
5
        Wert    : out std_ulogic_vector(7 downto 0)
6
    );
7
end entity Gemeinsam;
8

9
architecture Verhalten of Gemeinsam is
10
    signal Zaehler      : integer range 0 to 255;
11
    constant Maximal    : integer:=20;
12
begin
13
    process(clk)
14
    begin
15
        if rising_edge(clk) then
16
            if reset='1' then
17
                Zaehler<=0;
18
            else
19
                if Zaehler=Maximal then
20
                    Zaehler<=0;
21
                else
22
                    Zaehler<=Zaehler+1;
23
                end if;
24
            end if;
25
        end if;
26
   end process;
27
  
28
   Wert<=std_ulogic_vector(to_unsigned(Zaehler,8));
29
end Verhalten;

Im Studium wurde es wohl so gelehrt, mit zwei Prozessen
1
entity Getrennt is
2
    port(
3
        clk     : in std_ulogic;
4
        reset   : in std_ulogic;
5
        Wert    : out std_ulogic_vector(7 downto 0)
6
    );
7
end entity Getrennt;
8

9
architecture Verhalten of Getrennt is
10
    signal Zaehler        : integer range 0 to 255;
11
    signal Zaehler_nach   : integer range 0 to 255;
12
    constant Maximal      : integer:=20;
13
begin
14
    process(clk)
15
    begin
16
        if rising_edge(clk) then
17
            Zaehler<=Zaehler_nach;
18
        end if;
19
    end process;
20
  
21
    process(reset,Zaehler)
22
    begin
23
        if reset='1' then
24
            Zaehler_nach<=0;
25
        else
26
            if Zaehler=Maximal then
27
                Zaehler_nach<=0;
28
            else
29
                Zaehler_nach<=Zaehler+1;
30
            end if;
31
        end if;
32
    end process;
33
  
34
    Wert<=std_ulogic_vector(to_unsigned(Zaehler,8));
35
end Verhalten;

Ob ich das in der zweiten Version so richtig hinbekommen habe, weiß ich 
nicht ganz genau, weil ich diese Schreibweise eigentlich nicht verwende. 
Zumindest funktioniert es in der Simulation.
Es geht darum, ob in diesem Beispiel das Zaehler+1 in dem getakteten 
Teil stehen soll oder in einem eigenen Prozess.
Es gibt die Regel, dass man rein kombinatorische Prozesse oder rein 
sequentielle Prozesse verwenden soll, aber das bezieht sich doch eher 
auf sowas wie
1
process(clk)
2
begin
3
    if rising_edge(clk,[andere Signale]) then
4
        [Anweisungen]
5
    end if;
6

7
    Signal<=[Kombinatorik aus anderen Signalen]
8
end process;
oder?

Mir fällt auf, dass die zweite Variante eine Verzögerung von einem Takt 
hat. Außerdem muss der kombinatorische Prozess eine Senstitivity-List 
mit vielen Signalen haben, wodurch es leicht zu Fehlern kommen kann. 
Deshalb bevorzuge ich die erste Version. Aber irgendeinen Grund muss es 
doch geben, dass die zweite gelehrt wird.
Was meint ihr, welche ist besser, welche benutzt ihr, welchen Grund gibt 
es, die eine zu benutzen und nicht die andere?
(Firma: Appsys ProAudio) #4605222
Lesenswert?

Ich persönlich finde die 1-Prozess-Methode leichter lesbar (komme aber 
von C her und habe deshalb vielleicht andere Präferenzen).

Ansonsten kann ich noch den Guru (Lothar Miller) zitieren, er sagt über 
die 2-Prozess-Darstellung: "Aber wer sich den Code ein halbes Jahr 
später anschaut, wird den Kopf schütteln, und sich fragen, wie und was 
da wann wozu verwendet wird". Der vollständige Text, sehr lesenswert 
(wie auch alles andere auf seiner Seite):

http://www.lothar-miller.de/s9y/archives/43-Ein-oder-Zwei-Prozess-Schreibweise-fuer-FSM.html
Moderator (Firma: Titel) Persönliche Seite #4605226
Lesenswert?

Dussel schrieb:
> Darf man getaktete Zuweisung und Kombinatorik mischen oder sollte das in
> zwei Prozessen getrennt sein.
Man darf im Prinzip, was man will...

Aber man sollte es nicht "mischen" in dem Sinn, dass Takte und 
Kombinatorik im Prozess beliebig durcheinander kommen (aus wenn das 
tatsächlich umgesetzt werden könnte):
1
entity Gemeinsam is
2
    port(
3
        clk     : in std_ulogic;
4
        reset   : in std_ulogic;
5
        Wert    : out std_ulogic_vector(7 downto 0)
6
    );
7
end entity Gemeinsam;
8

9
architecture Verhalten of Gemeinsam is
10
    signal Zaehler      : integer range 0 to 255;
11
    constant Maximal    : integer:=20;
12
begin
13
    process(clk, Zaehler)
14
    begin
15
        if rising_edge(clk) then
16
            if reset='1' then
17
                Zaehler<=0;
18
            else
19
                if Zaehler=Maximal then
20
                    Zaehler<=0;
21
                else
22
                    Zaehler<=Zaehler+1;
23
                end if;
24
            end if;
25
        end if;
26
        Wert<=std_ulogic_vector(to_unsigned(Zaehler,8));
27
   end process;
28
  
29
end Verhalten;

Der Rest ist die Dskussion um die 1-Prozess vs. 2-Prozess-Beschreibung. 
Hierzu ein paar Worte:
http://www.lothar-miller.de/s9y/archives/43-Ein-oder-Zwei-Prozess-Schreibweise-fuer-FSM.html


> Mir fällt auf, dass die zweite Variante eine Verzögerung von einem Takt > hat.
Das kommt darauf an, welches Signal du ansiehst: den Eingang des 
Flipflops oder seinen Ausgang. Solche unerwartete "Latency" hast du eher 
mal, wenn du mit der 1-Prozess-Schreibweise neu beginnst...
(Firma: www.dossmatik.de) #4605238
Lesenswert?

Jetzt schreib ich mal meine Variante.
1
  process(clk)
2
    begin
3
      if rising_edge(clk) then
4

5
        if Zaehler=Maximal then
6
          Zaehler<=0;
7
        else
8
          Zaehler<=Zaehler+1;
9
        end if;
10

11

12
        if reset='1' then
13
          Zaehler<=0;               
14
        end if;
15

16
      end if;
17
   end process;

Die letzt Zuweisung gewinnt.
Wenn der Reset am Ende des Process ist, dann enfällt das else in der 
höchsten if-Ebene.
Moderator (Firma: Titel) Persönliche Seite #4605247
Lesenswert?

Rolf E. schrieb:
> How about that one?
Die Vermischung von Reset und Funktion ist verwirrend. Ich nehme den 
goldenen Zwischenweg:
1
  process begin
2
      -- beim nächsten Takt
3
      wait until rising_edge(clk);
4

5
      -- Funktion bearbeiten
6
      if Zaehler=Maximal then  Zaehler<=0;
7
      else                     Zaehler<=Zaehler+1;
8
      end if;
9

10
      -- Zum Schluss: Reset, weil die letzte Signalzuweisung "gewinnt"
11
      if reset='1' then        Zaehler<=0;               
12
      end if;
13
   end process;

Siehe dort unten:
http://www.lothar-miller.de/s9y/categories/34-Getakteter-Prozess

Rolf E. schrieb:
> Lothar, Du warst zu langsam!
Schlags kaputt... ;-)
Gast #4605499
Lesenswert?

Die Ein-, Zwei- und Dreiprozessschreibweise für Zustandsautomaten kenne 
ich, aber handelt es sich bei dem gezeigten denn um einen 
Zustandsautomaten?
Man kann natürlich die einzelnen Zählerstände als Zustände auffassen, 
aber ein praktischer Zustandsautomat wird es dadurch doch noch nicht, 
oder?

Rolf E. schrieb:
> Ich persönlich finde die 1-Prozess-Methode leichter lesbar (komme aber
> von C her und habe deshalb vielleicht andere Präferenzen).
Das geht mir genauso.

René D. schrieb:
> Gibt es einen Unterschied zwischen den beiden Anweisungen?
Gibt's da auch was von Lothar Miller?
Selbstverständlich: 
http://www.lothar-miller.de/s9y/archives/16-Takt-im-Prozess.html ;-)
Gast #4605529
Lesenswert?

Wir verwenden die 2Prozess-Methode ala Gaisler.

@TO:
Signale nicht in Sensitivity List:
Deshalb benutzt oben genannte Methode Records.

Ein Takt Delay:
Du machst eine Zuweisung von "Zaehler" statt "Zaehler_nach"

Das Reset kann/muss/sollte dann oben asynchron im clocked process 
stehen. Der Reset Release  muss synchron erfolgen.
Gast #4605707
Lesenswert?

Ja, ist Teil des Coding Styles.

Ich weiß auch dass andere Riesen nicht nach 2 Prozess machen.

Es ist halt, wie so oft, Religion. Clock Domain Crossing erhöht 
natürlich die Zahl an Prozessen...
Gast #4605726
Lesenswert?

In den Coding Standard steht nicht "tu es wie gaisler", aber ich würde 
meinen, dass wir im Wesentlichen dem folgen.
Ich kenne beides und finde auch beides ok. Beides hat +\-, wobei mir 
momentan die 2 Prozess Methode gut gefällt.

Wie gesagt: gefallen... kommt eh dasselbe raus, meistens hoffe ich.
Gast #4605799
Lesenswert?

Ich hab mich mit dem Thema auch schon öfters bschäftigt (meistens mit 
Focus auf SV, aber das ist ja nur die Sprache), deshalb hier meine 
(etwas längeren) 2Cents:

Ich bin auch ein Anhänger des "Gaisler Styles" 
(http://www.gaisler.com/doc/vhdl2proc.pdf). Die wichtigsten Vorteile für 
mich:
- im kombinatorischen Prozess steht rein die funktionale Beschreibung 
des Moduls, clock und reset sehen im eigenen Prozess. Durch die 
Schreibweise mit records entsteht nicht mehr Code als beim 1 
Prozessmodell.
- ich kann auch nicht getaktete Signale steuern
- im kombinatorischen Prozess kann ich zugewiesene Variablen 
weiterverwenden (ja, das wird selten benötigt)
- im Simulator kann ich sehr einfach zwischen Registern (alles was in 
dem Register record ist) und kombinatorischen Signalen unterscheiden.
- Manchmal ist es hilfreich in der Simulation die next state signale 
beobachten zu können
- ich definiere die Resetwerte als Konstante des Registerrecords, somit 
kann ich die Resetwerte gleich unterhalb von der Definiton des 
Registerrecords machen. Weiters kann ich den Reset öfters zuweisen ohne 
alles neu zu schreiben. Z.B. wenn es neben dem asynchronen Reset noch 
einen Synchronen (Soft) Reset gibt.

Das Problem mit dem Verwalten der Sensitivitylist gibts seit VHDL 2008 
eigentlich nicht mehr. Es gibt "process(all)"

Die Argumente hier von Lothar 
(http://www.lothar-miller.de/s9y/archives/43-Ein-oder-Zwei-Prozess-Schreibweise-fuer-FSM.html) 
kann ich nicht nachvollziehen. Meiner Meinung nach wird in diesem Post 
das 2 Prozessmodell nicht konsequent angewendet. Denn 'delay' ist das 
einzige Signal, das im getakteten Prozess maintained wird. Warum? Hier 
sollte nur "delay <= next_delay;" stehen und alles weitere wieder im 
kombinatorischen.
Gast #4605911
Lesenswert?

Novice schrieb:
> Ich hab mich mit dem Thema auch schon öfters bschäftigt (meistens mit
> Focus auf SV,
Das scheint mir Wesentlich. Wenn SW angekoppelt wird, sind 
zusammengefasste Datentypen vorteilhaft, da stimme ich zu. Allerdings in 
Designs, in denen ein hartes timing im Modul generiert wird, nicht. 
Alles, was IO ist, bekommt da nur einen Mehraufwand.

> - im Simulator kann ich sehr einfach zwischen Registern (alles was in
> dem Register record ist) und kombinatorischen Signalen unterscheiden.
Das ist aber eine Frage der Beschreibung:
Wenn man Präfixes sauber benutzt, hat man keinen Nachteil, es bleibt 
aber der Vorteil, dass es zwischen Record-Signalen und Variablen 
ausserhalb von Records keinen Unterschied gibt.

>  Z.B. wenn es neben dem asynchronen Reset noch
> einen Synchronen (Soft) Reset gibt.
Etwas, was es in einem sinnvoll aufgezogenen FPGA-Design niemals gibt 
:-)
Moderator (Firma: Titel) Persönliche Seite #4605944
Lesenswert?

Markus F. schrieb:
> Das mit dem "wait" kapiert nicht jeder Synthesizer.
Doch, inzwischen schon.  Vor 10 Jahren war das noch neu. Da gab es noch 
welche,  die Probleme hatten. Z.B. auch mit der Initialzuweisung an 
Signale...

Novice schrieb:
> Meiner Meinung nach wird in diesem Post das 2 Prozessmodell nicht
> konsequent angewendet. Denn 'delay' ist das einzige Signal, das im
> getakteten Prozess maintained wird. Warum? Hier sollte nur "delay <=
> next_delay;" stehen und alles weitere wieder im kombinatorischen
Richtig, und genau  das verstehen offenbar viele Anfänger nicht.  Such 
einfach mal hier im Forums nach "kombinatorische Schleife" oder 
"combinatorial loop". Dieser Fehler taucht laufend auf. Und zu 99% warst 
dann eben ein Zähler im kombinatorischen Prozess...

Novice schrieb:
> . Z.B. wenn es neben dem asynchronen Reset noch einen Synchronen (Soft)
> Reset gibt.
Welches FPGA kann das? Oder andersrum: warum sollte man etwas 
beschreiben, was hinterher nur umständlich und aufwändig in Hardware 
umgesetzt werden kann?
Ich sehe hier das selbe Problem wie bei der Softwareentwicklung: obwohl 
die Prozessoren schneller werden, werden die Programme langsamer und 
"fetter"...
Gast #4605961
Lesenswert?

Weltbester FPGA Pongo schrieb im Beitrag #4605911:
> Novice schrieb:
>> Ich hab mich mit dem Thema auch schon öfters bschäftigt (meistens mit
>> Focus auf SV,
> Das scheint mir Wesentlich. Wenn SW angekoppelt wird, sind
> zusammengefasste Datentypen vorteilhaft, da stimme ich zu. Allerdings in
> Designs, in denen ein hartes timing im Modul generiert wird, nicht.
> Alles, was IO ist, bekommt da nur einen Mehraufwand.
Mit SV meinte ich SystemVerilog.
Gast #4605975
Lesenswert?

@Lothar:
Aja, den entscheidenden Satz hab ich vorher überlesen:
>Jetzt könnte ich das Spiel genauso wie mit counter und next_counter machen,
>aber diesmal bin ich zu faul und nehme den Verzögerungszähler delay einfach
>gleich in den getakteten Teil:
Naja, mit dem Gaisler Style wird die Faulheit umgangen, da man das 
Signal auch nur einmal definieren muss.
Aber wie schon weiter oben erwähnt, 1 vs. 2 Prozesse ist eine 
Entscheidung des Entwicklers. Ein richtig oder falsch gibts nicht.
Gast #4606103
Lesenswert?

@Lothar:
Wird die 2 Prozess Methode richtig angewendet, gibt's die 
Kombinatorische Schleife gar nicht, da typischerweise stehen sollte:

S.count := Reg.count + 1;

Aber ja, weißt ja eh, "wenn man es richtig macht"... ;-)
Moderator (Firma: Titel) Persönliche Seite #4606156
Lesenswert?

Markus F. schrieb:
> Niemals nicht hab' ich das geschrieben!
Richtig, da zitiert die Foren-SW ein wenig ungünstig:
Markus F. schrieb:
> Meine
Markus F. schrieb:
> Niemals

Matthias schrieb:
> Wir verwenden die 2Prozess-Methode ala Gaisler.
Gaisler schafft es hier, einen Beschreibungsstil (genau diese 
2-Prozessmethode mit getrennter Weiterschaltlogik und Registern) der 
schon früh am Ende des letzten Jahrtausends in jedem Lehrbuch stand, im 
Jahre 2010 in neue Schläuche zu füllen und als frischen (und vor Allem: 
eigenen) Wein zu verkaufen...
Persönliche Seite #4607188
Lesenswert?

Dann wird es jetzt wohl Zeit, die Prozesslandschaft 4.0 zu definieren 
und noch eine weitere kompliziertere Methode als NEU einzuführen. Immer 
mal was Neues.


René D. schrieb:
> Die letzt Zuweisung gewinnt.
> Wenn der Reset am Ende des Process ist, dann enfällt das else in der
> höchsten if-Ebene.

Das ist eine Sache, die viele Firmen in ihren Richtlinien ausschließen, 
nämlich, dass die Reihenfolge der Anweisungen eine Rolle spielen darf.

Bevorzugt werden ALLE Signale in allen Zweigen klar und ausdrücklich 
beschrieben. Wenn es zu kompliziert wird und die Bedinungen zu unschön 
überlappen, dann werden eben mehrere Prozesse definiert und zwar einer 
für jedes Signal.

Das erleichtert das Debuggen, weil explizite Zuweisungen existieren und 
Denkfehler bei der manuellen Simulation, die man ja quasi durchführen 
muss, nicht aufkommen oder ausdrüclich einprogrammiert hätten werden 
müssen.

In der Gesamtbetrachtung ist es so, daß es momenten noch recht egal ist, 
welche Schreibweisen der oberen verwendet wird, aber das ändert sich, 
wenn komplexe Rechenalgorithmen eingebaut werden sollen.

In der Mehrprozessschreibweise muss man dann immer die 
Vorher-Nachhersignale definieren. Braucht kein Mensch.Wir benutzten ja 
die Hochsprache, um Zuweisungen implizit zu vollziehen und nicht die 
FF-Struktur aufmalen zu müssen.
Gast #4608223
Lesenswert?

Jürgen S. schrieb:
> In der Mehrprozessschreibweise muss man dann immer die
> Vorher-Nachhersignale definieren. Braucht kein Mensch.Wir benutzten ja
> die Hochsprache, um Zuweisungen implizit zu vollziehen und nicht die
> FF-Struktur aufmalen zu müssen.
Naja, schau dir mal den Gaisler Style genauer an.
Gast #4610814
Lesenswert?

Die Querverbindung kam über die Gaisler-Pamphlete und die fragwürdige 
Schlussfolgerung einiger Jünger, daß wenn eine Gaisler-Idee gut ist, der 
Rest auch gut sein müsse.

Eine spontane Umfrage in der hiesigen Abteilung ergab im Übrigen:

3 kennen das gar nicht
4 kennen das, benutzen es aber nicht
2 kennen das, benutzen es nur teilweise
1 kennt es und hält sich weitgehend dran

Das ist ein Anteil von 14% derer, die es kennen. In ganz Deutschland 
gibt es also unter allen 44000 embedded Ingenieuren rund 6000 
Gaisler-Jünger.

Bagwhan hatte zu seinen Besten Zeiten 100mal mehr. Da gibt es also noch 
Überzeugungsarbeit zu leisten :D

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren