Forum: FPGA, VHDL & Co. [VHDL] Komplexität von Prozessen


von Jan K. (frittenfett)


Lesenswert?

Hallo zusammen,

ich habe eine Frage zur Komplexität von Prozessen. Damit meine ich wie 
viel Funktionalität in einem Prozess sein sollte.

Ein kleines, sehr vereinfachtes Beispiel. Ich habe zwei Prozesse. Der 
erste Prozess ist ein einfacher Zähler. Der zweite Prozess generiert ein 
Valid Signal, wenn der Zählerwert Null ist.
1
counter_process : process(clk50mhz, reset_n)
2
begin
3
    if reset_n = '0' then
4
        r_counter <= (others => '0');
5
    elsif rising_edge(clk50mhz) then
6
        r_counter <= r_counter + 1;
7
    end if;
8
end process;
9
10
valid_process : process(clk50mhz, reset_n)
11
begin
12
    if reset_n = '0' then
13
        r_valid <= '0';
14
    elsif rising_edge(clk50mhz) then
15
        if r_counter = 0 then
16
            r_valid <= '1';
17
        else
18
            r_valid <= '0';
19
        end if;
20
    end if;
21
end process;

Man kann das Beispiel in zwei Prozessen schreiben oder auch in einem.


Meine Frage ist, gibt es ein Best Practice für die Komplexität eines 
Prozesses? Also schreibt man alles was passt in einem Prozess oder 
bricht man die Funktion auf kleine Prozesse runter? Wie handhabt ihr 
das?

Hat die Entscheidung sogar Auswirkungen auf den Fitter? Könnte er im 
Worst Case den Zähler links unten und das Valid Signal rechts oben 
platzieren?

Ich hoffe, ihr versteht worauf ich hinaus möchte.

Liebe Grüße

Jan

von Martin S. (strubi)


Lesenswert?

Jan K. schrieb:
> Meine Frage ist, gibt es ein Best Practice für die Komplexität eines
> Prozesses? Also schreibt man alles was passt in einem Prozess oder
> bricht man die Funktion auf kleine Prozesse runter? Wie handhabt ihr
> das?

Da werden dich wieder zig Fachleute mit unterschiedlichen Meinungen 
zudroehnen - also, ein Klassiker: Bild' Dir deine eigene Meinung.

Stichworte:
- Gaisler-Ansatz bei FSMs (state of the art)
- Simulator-Aspekte, je nach Simulator kann es einen Unterschied 
(Geschwindigkeit) machen, wie man die Prozesse gestaltet
- Logik: Macht es Sinn, eine Verzoegerung (siehe r_counter gegen 
r_valid) explizit oder implizit 'hinzuschreiben'

Deswegen nur mein Credo: Lesbarkeit. Bei einer Pipeline wuerde ich die 
einzelnen Prozess-Stufen ('stages') kennzeichnen. Beim Debuggen von 
langen schlecht lesbaren process'es verbraet man am meisten Zeit.

Jan K. schrieb:
> Hat die Entscheidung sogar Auswirkungen auf den Fitter? Könnte er im
> Worst Case den Zähler links unten und das Valid Signal rechts oben
> platzieren?

Nee, ein solch unzulaengliches Synthesetool hab' ich noch nicht gesehen 
:-)

von Gustl B. (-gb-)


Lesenswert?

Also wenn reset_n = '0' dann wird auch der counter auf 0 gesetzt.

Und im zweiten Prozess wird r_valid <= '0'; gesetzt wenn reset_n = '0' 
ist, aber if r_counter = 0 then r_valid <= '1'; ? Aber das ist doch auch 
dann der Fall wenn reset_n = '0'.

Verstehe nicht, was du da machen möchtest.

Für mich sieht das so aus, als möchtest du nach einem Reset eine Zeit 
warten und dann erst dein valid setzen.

Ich mache das so:
1
begin
2
    wait until rising_edge(clk50mhz);
3
    valid <= '0';
4
    if r_counter < r_counter_max then
5
        r_counter <= r_counter + 1;
6
    else
7
        valid <= '1';
8
    end if;
9
    if reset_n = '0' then
10
        r_counter <= (others => '0');
11
    end if;
12
end process;

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


Lesenswert?

Martin S. schrieb:
> Stichworte:
> - Gaisler-Ansatz bei FSMs (state of the art)
Echt jetzt? Das mit dem Hin- und Herkopieren auf lokale Variablen? Damit 
man VHDL wie in Software programmieren kann?

> - Logik: Macht es Sinn, eine Verzoegerung (siehe r_counter gegen
> r_valid) explizit oder implizit 'hinzuschreiben'
Niemals "Pseudoverzögerungen" in synthetisierbaren Code! Das kann z.B. 
in einer kombinatorischen Schleife urige Effekte geben, wo der Simulator 
nie drauf kommt...

> Jan K. schrieb:
>> Hat die Entscheidung sogar Auswirkungen auf den Fitter? Könnte er im
>> Worst Case den Zähler links unten und das Valid Signal rechts oben
>> platzieren?
> Nee, ein solch unzulaengliches Synthesetool hab' ich noch nicht gesehen
Wenn man dem Placer (einen Fitter braucht es für CPLDs) keine Vorgaben 
in den Constraints macht, dann fängt er einfach irgendwo an und packt 
das Zeug vom Synthesizer der Reihe nach irgendwohin. Und wenn der 
Synthesizer auf dumme Ideen kommt, dann kann das schon passieren.

Und dass der Synthesizer auf dumme Ideen kommen kann, kann man sich 
schon daraus ableiten, was er aus gleichen Beschreibungen macht, die nur 
anders formatiert sind. Siehe das Beispiel dort zum Schluss:
http://www.lothar-miller.de/s9y/archives/52-Kompakte-Flankenerkennung.html

> ein Klassiker: Bild' Dir deine eigene Meinung.
So ist es. Sieh dir Code von anderen an. Übernimm den Stil, den du am 
besten lesen kannst.

: Bearbeitet durch Moderator
von Jan K. (frittenfett)


Lesenswert?

Vielen Dank für Eure Antworten.

Gustl B. schrieb:
> Also wenn reset_n = '0' dann wird auch der counter auf 0 gesetzt.
>
> Und im zweiten Prozess wird r_valid <= '0'; gesetzt wenn reset_n = '0'
> ist, aber if r_counter = 0 then r_valid <= '1'; ? Aber das ist doch auch
> dann der Fall wenn reset_n = '0'.
>
> Verstehe nicht, was du da machen möchtest.

Das war ein einfachen Beispiel welches ich mir aus den Fingern gesogen 
habe. Dass es nicht praktisch sinnvoll ist, weiß ich auch. Mir ging es 
nur darum meine Frage zu verdeutlichen.

von Christoph Z. (christophz)


Lesenswert?

Lothar M. schrieb:
> Martin S. schrieb:
>> Stichworte:
>> - Gaisler-Ansatz bei FSMs (state of the art)
> Echt jetzt? Das mit dem Hin- und Herkopieren auf lokale Variablen? Damit
> man VHDL wie in Software programmieren kann?

Wir machen hier alles im Gaisler Stil aber ohne dieses 
Variablen-gedöhns. Das war mir beim ersten lesen seines Papers schon 
irgendwie suspekt.

Man kann so sehr aufgeräumte Beschreibungen machen (hier gibt es 
natürlich auch Gebenbeispiele...). Richtig angewendet, werden auch nur 
die FFs erzeugt die gewünscht sind, die anderen werden zu 
Latches/Kombinatorische Schlaufen, die dann Reported werden (Auch hier 
gibt es leider Gegenbeispiele wo Latches ausgeliefert wurden).

von Markus F. (mfro)


Lesenswert?

das kann man sogar in einer einzigen Zeile schreiben (VHDL 2008):
1
...
2
architecture rtl of tst is
3
begin
4
    (r_counter, r_valid) <= std_logic_vector'((("00000000"), '1')) when rising_edge(clk) and reset_n = '0'
5
                            else std_logic_vector'(((std_logic_vector(unsigned(r_counter) + 1)), '0'));
6
end architecture rtl;

(kann bloß nicht jedes Tool mit umgehen...)

P.S.: gut, ich hab' zwei Zeilen draus gemacht ;)

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


Lesenswert?

Christoph Z. schrieb:
> Wir machen hier alles im Gaisler Stil aber ohne dieses Variablen-gedöhns.
Gerade das ist doch aber das Neue daran: dass Variabeln Wertänderungen 
sofort übernehmen und deshalb keine Probleme mit Latency auftreten 
können.

Denn dass man Signale über Records in Module einschleust, damit die 
leitchter erweiterbar/änderbar sind, das gibts ja schon lange.

von Christoph Z. (christophz)


Lesenswert?

Lothar M. schrieb:
> Denn dass man Signale über Records in Module einschleust, damit die
> leitchter erweiterbar/änderbar sind, das gibts ja schon lange.

Aber ausser das Paper von Jiri Gaissler kenne ich keine Quelle, die das 
mit Beispielen dokumentiert. Alle Lehrbücher, die ich kenne, hören 
vorher auf und die Codes die bis dahin gesehen hatte, verwendeten das 
nicht (bzw. Stile die ich nie selber anwenden will).

Für mich war damals Jiris Paper ein Augenöffner, wie man VHDL eigentlich 
nutzen kann. Bei den Programmierern gibt es da ja diverse Bücher über 
Design Patterns, Advanced concepts in... etc. So etwas vermisse ich für 
VHDL.
Bleibt mir halt das uC Forum :-)

von Martin S. (strubi)


Lesenswert?

Lothar M. schrieb:
> Echt jetzt? Das mit dem Hin- und Herkopieren auf lokale Variablen? Damit
> man VHDL wie in Software programmieren kann?

Macht in komplexen Designs (CPUs) durchaus Sinn und die Sache einiges. 
lesbarer. Bloss nicht wieder das alte Fass aufmachen, das wurde hier 
schon zigfach durchgekaut.
Grade der Gaisler-Ansatz kann auch die Ausfuehrungszeit der Simulation 
optimieren.

Lothar M. schrieb:
> Niemals "Pseudoverzögerungen" in synthetisierbaren Code! Das kann z.B.
> in einer kombinatorischen Schleife urige Effekte geben, wo der Simulator
> nie drauf kommt...

Ich meine einen clock delay..
Das gehoert dann auch wieder ins Thema Variable vs. Signal.
Haeufiger Denkfehler: Vergleich gegen ein Signal, was erst im naechsten 
Takt valide ist. Sehr muehsam, das durch einen schlecht strukturierten 
Code zu tracen (ohne Simulator).

Lothar M. schrieb:
> Wenn man dem Placer (einen Fitter braucht es für CPLDs) keine Vorgaben
> in den Constraints macht, dann fängt er einfach irgendwo an und packt
> das Zeug vom Synthesizer der Reihe nach irgendwohin. Und wenn der
> Synthesizer auf dumme Ideen kommt, dann kann das schon passieren.
>
> Und dass der Synthesizer auf dumme Ideen kommen kann, kann man sich
> schon daraus ableiten, was er aus gleichen Beschreibungen macht, die nur
> anders formatiert sind. Siehe das Beispiel dort zum Schluss:

Wie gesagt, solche Synthesizer habe ich lange nicht mehr gesehen, da 
wird optimiert, dass kein Mensch mehr durchblickt.
Und der Technology-Mapper packt typischerweise das Zeug so, dass es PNR 
nicht unnoetig aufm Quadranten verteilt. Bei so einem simplen 
process-Beispiel sowieso nicht.

von C. A. Rotwang (Gast)


Lesenswert?

Jan K. schrieb:
> Meine Frage ist, gibt es ein Best Practice für die Komplexität eines
> Prozesses? Also schreibt man alles was passt in einem Prozess oder
> bricht man die Funktion auf kleine Prozesse runter? Wie handhabt ihr
> das?

Es gibt 'Best practice' für Prozesse, die drehen sich aber nicht um so 
ein Pillepalle wie max. Zeilanzahl für process body. Die Grundregel, 
schreibe alles in einem Prozess was zu der Hardware-Komponente gehört. 
Also bei einem run-once-counter alles in einem, bei einer FSM, shiftreg, 
speicherblock,...

Dann sollte man sich auf wenige sensitivity-listen beschränken, bspw. 
nur getaktetet Prozesse mit synchronen reset, keine kombinatorischen 
Prozesse.

Man kann auch kombinatorische Prozesse verwenden, das ist IMHO aber 
fehlerträchtig.

Die sensitivity-listen müssen vollständig sein, dürfen aber keine 
ungenutzten Signal enthalten.

Für FSM bevorzuge ich die Ein-prozess Variante, wobei das 
Ausgangsnetzwerk auch schon mal ausserhalb dieses prozesses stehen kann 
(falls das signal ohne FF benötigt wird).

Bei Counter in Prozessen habe ich noch nicht den goldenen Mittelweg 
gefunden, also bspw. wait-cycle-counter im extra prozess oder im FSM 
prozess; ich tendiere diesen counter in den selben Prozess zu setzen.

Und nicht vergessen, wenn etwas zu lang oder zu unübersichtlich zu weren 
droht, kann man immer comments einschieben um zu erklären an welcher 
Stelle im Hardwaregestrüpp man sich gerade befindet, und was hier 
gemacht werden soll.

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.