Forum: FPGA, VHDL & Co. Do's und Do Not's


von TheMason (Gast)


Lesenswert?

Hallo,

ich möchte mal einen Thread für Einsteiger in die VHDL-Programmierung 
aufmachen in dem eine Sammlung von "Do's und Do not's" enstehen soll.
Es ist (gerade) für Leute die sich mit Software beschäftigen und dann 
mit VHDL in Berührung kommen eine kleine Hilfe aufwendige Fehlersuche zu 
vermeiden.

Ich mache mal den anfang :
(man möge mich korrigieren wenn ich quark-mist erzähle ...)



Do Not :
--------

process (...)
begin
  if clk'event and clk = '1' and clk_enable = '1' then
    ...
  end if;

end process;

Das ist ein gated Clock. Führt dazu das glitches auftreten können und 
der "gegatete" Clock nicht mehr 100% synchron zum eigentlichen Clock ist 
(lautzeit des und gatters). Böse Falle.


Do Not :
--------

Bsp :

signal a : std_logic;
signal b : std_logic;
signal c : std_logic;

process (clk)
begin
  if clk'event and clk = '1' then
  begin
    a <= b and c;
  end if;
end;

Man sollte immer alle beteiligten (eingangs-)signale in der sensivity 
list eines prozesses haben.
Sonst kann es passieren das der Synthesizer was anderes synthetisiert 
als man ursprünglich vorhatte zu implementieren (Beispiel Latch <-> 
Flipflop).

Es sollte dann heißen :

process (clk, b, c)
...

von Falk (Gast)


Lesenswert?

Erstes Don't stimmt so. Man sollte noch hinzufügen dass bei gated Clocks 
A) Glitches auftreten können und b) Clock Skew. Beides ist böse ;-)

Und man sollte noch die korrekte Version hinschreiben.

Das zweite ist falsch! Es gibt praktisch nur zwei Sorten von Prozessen, 
getaktete und rein kombinatorische. Erstere brauchen nur den Takt und 
ein evtl. vorhandenes asynchrones reset in der Sensitivity List, der 
Rest ist vollkommen egal und korrekt! Kombinatorische Prozesse brauchen 
natürlich alle Eingangsvariablen in der Sensitivity List, sonst gibts 
böse Simulationsfehler !!! (IIRC, Modelsim meldet keine Fehler bei 
fehlenden Signalen in der Sensitivity List, was auch vom Konzept von 
VHDL vollkommen in Ordnung ist). Das Syntheseergebnis wird AFAIK dadurch 
nicht verfälscht, weil die Compiler meist gutmütig genug sind, und 
"intern" alle Eingangsvariablen in die Sensitivity List eintragen 
(während der Synthese).

MfG
Falk

von Mahnender (Gast)


Lesenswert?

Ich bin absolut dafür, daß nur KOMPETENTE Personen sich aufschwingen, 
und dd-Listen in Newsgroups posten, sodaß nichr diskutiert werden muss. 
sonst bringt man den Leuten noch einen Mist bei

von Karl (Gast)


Lesenswert?

> sonst bringt man den Leuten noch einen Mist bei

so what?
TheMason bekommt seine Selbstbestätigung, ein Neuling glaubt etwas Mist. 
Maßt du dir an zu beurteilen ob die Nachteile die Vorteile überwiegen?

von Jens (Gast)


Lesenswert?

Wie wäre es das ganze im Wiki zu hinterlegen?

von Fpgakuechle K. (Gast)


Lesenswert?

Ohne Anspruch auf allgeingültiges "mach immer" oder "Mach Nie"

Für VHDL Code der zu FPGA/CPLD synthetisiert wird:

-Nur Richtung IN und OUT an Ports verwenden, bei der Top Entity an
Tristate-Bussen auch IONOUT.

-Zuweisung auf Z nur in der architecture der TOP Entity.
(das thema interne Tristates bei Spartan2/2E lassen wir hier aus)


-Genau eine Bibliothek mit unsigned verwenden.
 (also nicht USE IEEE.numeric_std.all,USE IEEE.std_logic_arith.all, ... 
in einem File oder in mehreren Files zu einem Design) mischen


-Möglichst Nur prozesse mit Takt und  evt. asynchronen reset verwenden
 Siehe Vorredner. Kombinatorische Prozesse (prozess ohne clk, aber allen 
anderenEingangssignalen in der sense list) nur bei Strukturen mit 
wählbarer Bitbreite einsetzen.


-für Indezies von vectoren Zählrichtung und grenze nicht mischen.
 ( also nur ...(.. DOWNTO 0) verwenden.

-feldattribute wie 'range 'low 'high benutzen
-die feldattribute 'left 'right nicht benutzen

-eigene Typen definieren, nicht nur für FSM:
1
         ausgang_o <= adu1_wert_i      when mux_select = ADU else
2
                      Status_reg_q     when mux_select = STATUS else
3
                      C_Version_number when mux_select = VERSION;

-beautifier benutzen (z.b Emacs vhdl mode)

-Prä/postfixe an signal namen etc. verwenden
z.B. o für Ausgangsport  _i für Eingänge _q für Signale aus FF V für 
variablen

...

von J. S. (engineer) Benutzerseite


Lesenswert?

Die Signalnamen auf den verschiedenen Designebenen geignet benennen, 
sodaß z.B: verbindende Signale auf der top level Ebene immer mit tl_ 
anfangen, in einem modul, daß z.B. uart realisiert, alle signale mit 
ua_.

Richtungskritsche Signale , die Instanzen verbinden immer als "from-to", 
d..h. tl_data_mctrl_ram wäre ein top level Datensignal VOM main 
controller ZUM Ram. Damit verdeutlichlicht sich die Datenrichtung. 
Vermeiden sollte man betrachtungsabhängige Bezeichung, wie IN und OUT, 
sondern lieber "to_modul_x" oder "from_data_modul_x". Damit ist die 
Flussrichtung klar und man kann auch anonym deklarierte Ports iwe "in, 
out" fehlerfrei ohne Nachzudenken andrahten. Optimal ist es natürlich, 
wenn auch die Ports der Komponenten und Instanzen einddeutige Ins und 
Outs haben. Oft sehe ich aber leider designs, wo Ins mit Ins und Ins mit 
Outs verbunden sind, die Betrachtung als mischt.

Für Komponenten empfiehlt sich eine Gruppierung der Ports in System, In, 
InOut und Out, bei "System" die für den Betrieb und Test nötigen Signale 
enthält, während die anderen 3 echte logische Datenpfade sind. So kennt 
ein Videocontroller (vc), der einen Datentakt aber natürlich auch noch 
einen FPGA-Systemtakt hat und zu Testzwecken abgeschaltet und 
paramteriert werden kann, folgende Signale: (downtos für Buse 
weggelassen und auch suffixe _i, _o fallen an den ports dann weg, dann 
in und out ja klar wird)

-- system
vc_fpgaclock_i, vc_test_enable_i, vc_testpattern_i, vc_test_error_o
-- inputs
vc_ videoclock, vc_data_from_adc, vc_from_dsp_chain, vc_adr_from_dsp, 
vc_test_image
-- inouts
vc_video_databus
-- outputs
vc_vid_signals_out, vc_to_statusreg, vc_to_dsp_chain, vc_error_out

Man beachte z.B. die dsp_chain Verdrahtung sowie die Tatsache, daß der 
FGPA-Clock ein FPGA-Signals, während der Videotakt ein 
Applikationssignal darstellt, das es auch in einer Analogelektronik 
gäbe. Man unterscheide vor allem auch die Testmuster, die man in jedem 
Modul eines jeden FPGA-Designs anlegen könnte, um Module anzuregen, 
Standarddaten zu senden (System) und das Videotestmuster, dass es nur in 
einem Video-FPGA gibt, ergo bei den operational signals steht.

Das, was hier im Bereich System steht, könnte (und sollte?) also in 
JEDEM FGPA-Desing zu finden sein, zumindest bei logisch komplex 
agierenden Modulen mit vielen Zustanden und Datenoperationen.

von Jannulis T. (tembridis)


Lesenswert?

Bei größeren Designs lohnt der Einsatz von Mentor's FLI. Ersatzmodelle 
in C können aufwendige Simulationen deutlich beschleunigen (natürlich 
ist ein Ersatzmodell immer mit Vorsicht zu behandeln). Ausserdem lassen 
sich per FLI sehr bequem große Datenmengen in das eigene Design 
einspeisen bzw. daraus abführen (z.B. Videosequenzen).

von FPGA-User (Gast)


Lesenswert?

Sinnvoll:

* Lesbaren Code schreiben
- einheitliche Notation
- sinnvolle Signalnamen
- alles ordentlich einrücken
- Kommentare einfügen
- File-Header mit Autor, Kurzbeschreibung, evt. History
- kurze Bezeichner wählen
- alle Möglichkeiten von VHDL konsequent nutzen
- keinen Code schreiben, der aussieht wie von einem Tool erzeugt ;-)
- rising_edge() falling_edge() anstelle des unsäglichen clk'EVENT and 
clk='1'...

* Synchrone Designs erstellen
- in einem synchr. Design sind alle Signale synchron zu einem Takt, auch 
die I/O-Signale
- manchmal benötigt man mehrere Clocks, diese sollten ebenfalls alle 
synchron sein

* sparsam mit Variablen umgehen
- Variablen können zu unerwünschten Effekten führen, wenn man den 
Unterschied zu Signalen nicht verstanden hat. Deshalb so viele Signale 
wie möglich

* Wiederverwendbaren VHDL-Code schreiben
- mit Generics arbeiten
- Konstanten in Packages verwenden
- klare Gliederung des Codes
- Bitbreiten sollten leicht anzupassen sein, also wie schon oben 
beschrieben mit Feldattributen arbeiten, dabei gibt es keine Verbote
- wenn möglich und sinnvoll, dann alles parametrierbar machen

... die Liste ist unvollständig ...

Noch ein paar Bemerkungen zu dem, was ich weiter oben gelesen habe:

'Zuweisung auf Z nur in der Top-architecture' ... was soll der Unfug, 
ich möchte im Prozessor-Interface oder im I2C-Core schon Z zuweisen 
können!

'Signalnamen mit Präfix für die Hierarchieebene' ... jedes Synthese- und 
Simulationstool kann mit Hierarchien umgehen, das habe ich noch nie 
benötigt

Kombinatorische Prozesse sind genauso erlaubt wie getaktete. Wie soll 
man sonst z.B. den Adressdecoder für ein Prozessorinterface beschreiben?

Dafür krieg ich jetzt bestimmt Klassenkeile, aber ich würde sagen: Leute 
die keine ausreichende Erfahrung mit VHDL haben, sollten keine DOs und 
DONTs schreiben. Das schafft mehr Verwirrung als Aufklärung und führt zu 
irgendwelchen Mythen.

von Stefan W. (wswbln)


Lesenswert?

FPGA-User schrieb:
>- rising_edge() falling_edge() anstelle des unsäglichen clk'EVENT and
>clk='1'...

...dagegen habe ich gerade heute bei einem kleinen Modul namens 
"simple_SPI" verstossen, denn mit
> if clk'event and clk=activeClockLevel then ...
liess sich schnell und einfach via Generic der SPI-Mode definieren.

(Geht sicher auch anders, aber ich hab' das Modul nur schnell mal 
heruntergeklopft...)

von FPGA-User (Gast)


Lesenswert?

Hi Stefan,

klar, in dem Falle ist das sinnvoll - sind ja alles keine Gesetze, 
sondern nur Vorschläge.
Aber da muss man wirklich wissen was man tut. Ich kenne das Design 
nicht, aber der Wechsel auf eine andere Taktflanke könnte auch dazu 
führen, dass nichts mehr geht.
Die Code-Lesbarkeit halte ich übrigens für genauso wichtig wie synchrone 
Designs und Timing-Constraints, nichts ist schlimmer, als ein Stück VHDL 
bei dem man erst wieder Stunden braucht um durchzublicken.

von Falk (Gast)


Lesenswert?

> - manchmal benötigt man mehrere Clocks, diese sollten ebenfalls alle
> synchron sein

Das ist aber ein wenig unverständlich. Wenn ich mehrere Taktblöcke 
(Clock domains) habe, dann können die ruhig zueinander asynchron sein 
(sind es meist auch), allerding die einzelnen Blöcke an sich sind ein 
synchrones Design. Der Übergang von Daten und Steuersignalen muss dann 
vorichtig und gemäss bekanter Reglen erfolgen (Asynchrone FIFOs, 
Synchonizer FlipFlops, Gray Code, etc.)

MFG
Falk



von J. S. (engineer) Benutzerseite


Lesenswert?

"'Signalnamen mit Präfix für die Hierarchieebene' ... jedes Synthese- 
und
Simulationstool kann mit Hierarchien umgehen, das habe ich noch nie
benötigt"

Das genau ist der häufig gemachte Denkfehler. Es geht nicht darum, daß 
das Tool es etwa nicht könnte oder man sich selber nicht zurecht findet, 
sondern um das Erkennen und Wiedererkennen durch andere Teamarbeiter, 
wenn sie sich in einem Design zurechtfinden müssen. In vielen Tools oder 
nach Export der Netzliste geht die vordergrüngie Hierarchie darüber 
hinaus verloren.

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.