Ich habe nun begonnen, mich mit VHDL zu beschäftigen, habe mir den
Reichardt angeschafft (bis zur hälfte "gelesen") und modelsim
installiert.
Obwohl ich bereits in der Lage bin, einfachere Aufgaben zu bewältigen,
habe ich immer so ein komisches Gefühl dabei, da ich nie weiß, ob ich es
auch "richtig" mache.
Bei einem Programm für eine CPU kann ich besser abschätzen, was gut und
schlecht sein wird, während ich keine Ahnung habe, was aus einem VHDL
Entwurf nach der Synthese herauskommt.
Beispiel:
Als Spielerei (!!) habe ich ein Beispiel so umgebaut, dass die Funktion
mit unsigned statt bit_vector variablen rechnet. So kann ich bis 10
Zählen und setze dann den Zähler wieder auf 3. Das ginge auch anders mit
"00001010" und "00000011" und einem bit_vector. Wie wirkt sich das nun
aus? Ich tue mir schwer vorzustellen, wie die Variablen einer Funktion,
die in einem Prozess verwendet wird umgesetzt werden. Wie werden z.B.
Konvertierungsfunktionen umgesetzt? Als vordefinierte Einheit, die dann
eingebunden wird?
Gibt es hier allgemeine Regeln oder ist alles bloß Erfahrung?
Danke und Grüße
Michael
Ohne zu Dir und Deinen Code-Überlegungen im Detail Stellung nehmen zu
wollen, erlaube ich mir die Bemerkung, dass die Art der Annäherung an
das Thema VHDL sagen wir mal, "ungewöhnlich" ist!
Wenn ich mir vorstelle, dass ein simples count Problem wie dieses,
demnächst generell so gelöst wird, bzw der Code von vielen Entwicklern
so aussieht, dann schwanke ich zwischen Erschiessen und Erhängen.
Ein kleiner Exkurs dazu: In der Industrie kommt es darauf an, ein
Problem möglichst vollständig und dabei einfach und schnell zu lösen.
Eine jede Beschreibung (und VHDL ist hier eine Beschreibung einer
Problemlösung) sollte demgemäss einfach erfassbar und durchsichtig sein.
Je mehr aus dem Code direkt ersichtlich ist, desto weniger muss
dokumentiert werden.
Niemand zahlt VHDL Entwickler für schönen und komplexen Code, sei er
auch noch so elegant. Daher ist es generell unzweckmässig, die Tiefen
und Breiten dieser Sprache in allen Einzelheiten auszureizen oder dies
zu versuchen. Preise für elegantes VHDL, die von einer Komission für
modernes EDA vergeben würden, sind mir nicht bekannt.
Das war jetzt nicht die Anwort auf Deine Frage, aber ich höffe, sie
hilft Dir trotzdem etwas weiter.
Welche Strategien und Überlegungen werden denn diesbezüglich von den
Profs so kommuniziert? Gibt es da nur VHDL-Vorlesungen oder auch
Hinweise, worauf es ankommt? - Täte mich mal so interessieren.
Je nach IDE kannst Du Dir eine RTL-Schaltung anzeigen lassen. Das
ISE-Webpack kann das.
Das gibt dem, der sich mal mit dem Aufbau von Schaltung auf Gatterebene
beschäftigt hat, eine Vorstellung auf welchem Größen- und
Komplexitätsebenen er sich bewegt.
@Weltbester FPGA-Pongo:
Hallo und danke für die Antwort!
Das Beispiel diente für mich lediglich als Spielwiese für das, was ich
im Buch lesen durfte. Dass man einen simplen Zähler einfacher abbilden
kann ist mir bekannt, war aber nicht das Thema. Irgendwo muss man ja
ausprobieren dürfen, ohne gleich eine hochkomplexe Industrieschaltung zu
realisieren.
Wieso ist mein Zugang ungewöhnlich bzw. andersrum gefragt, wie müsste er
sein, um als "normal" zu gelten? Jemand der C lernt wird sich anfangs
auch ein wenig mit Syntax und Sprachelementen herumspielen, oder? Ich
habe halt das Buch genommen, und Kapitel für Kapitel durchgenommen samt
Übungen...wie sonst?
Ich gehe auf keine Uni sondern möchte mir VHDL privat anschauen, da es
sowas zu meiner Zeit (habe meine Ausbildung in den frühen 80-ern
abgeschlossen) nicht gab und ich es hochinteressant finde, dass man auf
diese Weise "Hardware" synthetisieren kann. Damals lernte ich, wie man
Digitalschaltungen von Hand designte, jetzt ist das scheinbar anders...
Wenn man eine Bildungslücke schließen will, muss man ja nicht gleich in
dem Gebiet als Profi arbeiten...Dass ich als Hobbyist nicht weit kommen
werden, ist mir sowieso klar, aber es macht mir halt trotzdem Spaß...
Michael W. schrieb:> Damals lernte ich, wie man> Digitalschaltungen von Hand designte, jetzt ist das scheinbar anders...
Wenn Du von Digitalschaltungen eh schon Ahnung hast, dann besteht ja
Hoffnung :-)
Ich kann mich erinnern, dass mir VHDL am Anfang auch komplett
unverständlich und verwirrend war.
Du solltest Dir bewusst sein, dann man mit VHDL das Pferd von hinten
aufzäunt.
Man beschreibt ein Verhalten, und der Compiler macht dann Hardware
daraus, das dieses Verhalten zeigt.
Wenn Du das Verhalten kompliziert beschreibst, mit Funktionen und so,
aber das Verhalten ist immer noch das eines Zählers bis 10, dann kommt
trotzdem immer ein Hardware Zähler bis 10 heraus.
Wenn Du das Ganze zu kompliziert beschreibts, dann kann es sein, dass
der Compiler das beschriebene Verhalten nicht mehr versteht, und die
falsche Hardware generiert. Aus diesem Grund gibt es IEEE Standards und
Handbüchern zu den Compilern, wo steht, was erlaubt ist.
Lies Dir z.B. einmal den User Guide zum XST oder "Xilinx Synthesis and
Simulation Design Guide", da steht drinnen, wie man ein FF oder eine FSM
beschreibt, damit's verstanden wird.
Michael W. schrieb:> count <= increment(count) after tpd_clk_to_count;
Keine symbolischen Delays in einer Hardwarebeschreibung verwenden! Das
kann böse ins Auge gehen:
Beitrag "Re: Frage zu Pseudozufallsgenerator!?"
Und welche 10% der Syntaxelemente von VHDL tatsächlich in Hardware
umgesetzt werden können, steht im User Guide des entsprechenden
Synthesizers...
Weltbester FPGA-Pongo schrieb im Beitrag #3711820:
> Ohne zu Dir und Deinen Code-Überlegungen im Detail Stellung nehmen> zu> wollen, erlaube ich mir die Bemerkung, dass die Art der Annäherung an> das Thema VHDL sagen wir mal, "ungewöhnlich" ist!
Ich finde deine Antwort an den TO als nicht sehr nett.
Um es hier mal auf den Punkt zu bringen:
1) Der TO will sich in ein neues Thema einarbeiten
2) Er hat sich ein Buch beschafft und dies auch angeschaut, und eine
Einarbeitung ist meiner Meinung nach ersichtlich.
3) Er hat eine konstrutive Frage gestellt: Ist meine Beschreibung so gut
und für die Toolchain brauchbar?
4) Er beschreibt schon sehr genau sein Problem: Er kann sich erstmal
nicht vorstellen, was genau die Toolchain aus seinem Code macht. (Viele
die hier mit FPGAs arbeiten, habe ich den Eindruck, dass sich diese
dieser Frage noch bei weitem nicht bewusst sind!)
5) Er hat Code geliefert und fragt nach einer Verbesserung!
6) Und das was viele nach mehrmaligen ermahnen nicht schaffen, der TO
simuliert seine Schaltung!!!
@ Weltbester FPGA-Pongo: Ich verstehe hier in keinster Weise deine
Kritik.
@ Michael:
Ich finde deine herangehensweise vorbildlich! Lass dich hier nicht
unterkriegen. Weiter so!
Ein Tipp von mir:
Du weißt schon, wie man digitale Schaltungen von Hand designed, dann
weißt du ja auch, wie dein Zähler in etwa als Logik aussehen soll. Die
Toolchains (Xilinx, Altera etc.) können ein Schematic von deiner
Implementierung ausgeben. Das könnte dir schonmal weiterhelfen, ob es in
etwa deiner Vorstellung entspricht.
Tricks, wie man etwas optimiert und bei gleicher Funktion
resourcenschonender und besser leserlich machen kann lernt man nicht von
Heute auf Morgen, sondern erst, wenn man viel damit gemacht hat. Man
bekommt irgendwann ein Gefühl dafür und man fängt einfach an in Logik zu
denken. z.B. in dieser Zeile "erzeuge" ich so und soviel FlipFlops, Bei
dieser Abfrage vergleiche ich 64 Signale auf größergleich (=komplizierte
Logik) -> kann man dies mit einer äquivalenten Abfrage vereinfachen?
Wie Lothar schon sage, die delays dienen eigentlich nur der Simulation
und können in HW nicht umgesetzt werden.
Meiner Meinung nach solltest du am Anfang auch auf Funktionen und
Proceduren verzichten. Die verleiten etwas schnell hinzuschreiben, was
dann aber aus unachtsamkeit viel Logik verursacht.
Kopf hoch und einen schönen Abend noch!
123abc schrieb:> Meiner Meinung nach solltest du am Anfang auch auf Funktionen und> Proceduren verzichten.
"Anfang" bedeutet hier in etwa "das erste (halbe) Jahr"...
Eine Funktion oder eine Prozedur und insbesondere eine Schleife ist in
VHDL etwas grundlegend Anderes als in einer Programmiersprache. Sowas
gehört bestenfalls in eine Testbench, aber nicht in die Hardware.
Meine Antwort bezieht sich hier auf die Synthese, nicht auf Testbenches
oder reine Simulation.
Michael W. schrieb:> Als Spielerei (!!) habe ich ein Beispiel so umgebaut, dass die Funktion> mit unsigned statt bit_vector variablen rechnet. So kann ich bis 10> Zählen und setze dann den Zähler wieder auf 3. Das ginge auch anders mit> "00001010" und "00000011" und einem bit_vector. Wie wirkt sich das nun> aus? Ich tue mir schwer vorzustellen, wie die Variablen einer Funktion,> die in einem Prozess verwendet wird umgesetzt werden.
Wie du wohl schon vermutest, kommt die typische Ingenieur Antwort:
"Kommt drauf an" :-)
Der Synthesizer analysiert die Beschreibung deines Prozesses und
entscheidet dann mal grundsätzlich, ob der Wert der Variablen immer
eindeutig bestimmt ist, wenn die Variable verwendet wird um einem Signal
einen Wert zu zu weisen.
Wenn das nicht der Fall ist, muss der Synthesizer Flip-Flops einbauen,
um den Variablen Wert zu speichern -> Wenn das so gewünscht ist,
solltest du besser ein Signal verwenden.
Wenn die Variable immer einen definierten Wert bekommt, unabhängig von
der Vergangenheit, dann baut der Synthesizer eine kombinatorische
Schaltung. Du kannst dir in solchen Fällen die Variable als
"Zwischenergebnis eines kombinatorischen Blocks" vorstellen. -> Hier ist
es OK eine Variable zu verwenden, wenn die Leserlichkeit erhöht wird.
Eine Funktion die synthetisierbar sein soll, sollte so geschrieben sein,
dass sie nur Kombinatorik beschreibt. Was in deinem Beispiel auch so
ist.
> Wie werden z.B. Konvertierungsfunktionen umgesetzt? Als vordefinierte> Einheit, die dann eingebunden wird?
Auch hier, je nach dem. Vielfach nutzt man werteingeschränkte
Integerdatentypen für Zähler und um Arrays etc. zu adressieren. Weil es
für uns besser lesbar ist und oft einfachere Beschreibungen ergibt.
Genau so wie bei einem Mikroprozessor auch, kann der FPGA aber kein
Dezimalsystem, sondern alle Integer werden als Binärzahlen dargestellt
und verwendet.
Im Endeffekt ist also die Konvertierung von/nach Integer gratis (schon
fast wie ein type cast).
Konvertierung nach z. B. real ist ein anderes Thema, das kostet Logik.
Aber niemand verwedet einen real Datentyp innerhalb eines FPGAs (Neu
auftauchende Lösungen für High-End FPGAs für High-End Probleme
ausgenommen).
-- THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS THE PROPERTY OF
7
-- MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS SUBJECT TO LICENSE TERMS.
8
--
9
10
entityotheris
11
port(count:bufferbit_vector(8downto1);
12
clk:inbit;
13
reset:inbit);
14
end;
15
16
architectureonlyofotheris
17
18
begin
19
20
process(clk,reset)
21
variableresult:bit_vector(8downto1):=count;
22
variablecarry:bit;
23
begin
24
if(reset='1')then
25
count<=(others=>'0');
26
elsifclk'eventand(clk='1')then
27
ifcount="00001010"then
28
count<="00000011";
29
else
30
carry:='1';
31
result:=count;
32
foriin1to8loop
33
result(i):=count(i)xorcarry;
34
carry:=count(i)andcarry;
35
exitwhencarry='0';
36
endloop;
37
count<=result;
38
endif;
39
endif;
40
endprocess;
41
42
endonly;
Der Simulator zeigt das gleiche Verhalten.
Nun die Quartus RTL Views:
1) test1
2) other
Obwohl ich bei der ersten Variante unnötige Konvertierungsfunktionen
verwendete (und auch eine Funktion...) ist das Ergebnis sehr einfach und
transparent.
Hingegen erscheint mir das Ergebnis im 2. Fall unnötig kompliziert,
abgesehen davon, dass ich nicht weiß, weshalb Ports erzeugt werden, die
im Modell nicht definiert sind (.._OUT0). Was hat es damit auf sich und
was ist nun "besser" ?
Danke für die Geduld mit einem Anfänger ;-)
Michael W. schrieb:> Was hat es damit auf sich und> was ist nun "besser" ?
Ich finde Variante 1 übersichtlicher.
Ich würde aber noch folgende Dinge ändern:
1. Index der Vektoren von (Breite-1 downto 0)
Dsa ist zwar erstmal ungewohnt, aber gibt weniger Probleme mit Code
aus dem Netz oder von Kollegen.
2. Statt dem Typ buffer in der Porbeschreibung verwendet man
üblicherweise ein internes Signal, welches dann dem out Port
zugewiesen wird.
3. Auf den Datentyp bit würde ich verzichten, zumal Du ja schon die
(mächtigere) Bibliothek ieee.std_logic_1164 einbindest.
4. Ich würde auf den Reset verzichten, wenn das Design ins FPGA kommen
soll und der Reset nicht unbedingt benötigt wird. Dazu gibt es unzählige
Diskussionen hier, daher jeder nach seinem Geschmak...
Bei mir würde der Code daher so aussehen:
Michael W. schrieb:> Obwohl ich bei der ersten Variante unnötige Konvertierungsfunktionen> verwendete (und auch eine Funktion...) ist das Ergebnis sehr einfach und> transparent.>> Hingegen erscheint mir das Ergebnis im 2. Fall unnötig kompliziert,> abgesehen davon, dass ich nicht weiß, weshalb Ports erzeugt werden, die> im Modell nicht definiert sind (.._OUT0). Was hat es damit auf sich und> was ist nun "besser" ?
Jetzt rein auf die beiden RTL Views bezogen:
Du hast einen einfachen Aufwärtszähler beschrieben. Also erwartest du
genau sowas wie im Bild "test1"
Das Bild "other" zeigt dir sofort, dass du nicht das bekommen hast, was
du beschreiben wolltest :-)
Lothar hat ja schon angemerkt:
Lothar Miller schrieb:> und insbesondere eine Schleife ist in VHDL etwas grundlegend Anderes als> in einer Programmiersprache
Sowas passiert, wenn der Synthesizer deine for Schleife ausrollt... (Er
berechnet die ganze Schleife gleichzeitig und parallel!)
Lothar Miller schrieb:> Eine Funktion oder eine Prozedur und insbesondere eine Schleife ist in> VHDL etwas grundlegend Anderes als in einer Programmiersprache. Sowas> gehört bestenfalls in eine Testbench, aber nicht in die Hardware.
Tut mir leid, aber so pauschal ist das grober und für Anfänger
verwirrender Unfug.
Werden Funktionen, Prozeduren und Schleifen anders umgesetzt als in
einer Programmiersprache? Sicher. Aber wenn einem dies klar ist, kann
man die auch gut einsetzen. Für Designs, die intensiv Generics nutzen,
sind Funktionen und Schleifen häufig sogar absolut unerlässlich.
greg schrieb:>> Eine Funktion oder eine Prozedur und insbesondere eine Schleife ist in>> VHDL etwas grundlegend Anderes als in einer Programmiersprache. Sowas>> gehört bestenfalls in eine Testbench, aber nicht in die Hardware.>> Tut mir leid, aber so pauschal ist das grober und für Anfänger> verwirrender Unfug.
Lothar meint wohl "selbstgeschriebene" Funktionen und Prozeduren,
rising-edge() oder to_unsigned() etc. aus synthesefähigen libraries sind
natürlich auch von Anfängern Nebenwirkungsfrei einsetzbar.
Auch aus meiner Sicht ist es sinnvoll und hilfreich VHDL-Anfängern
Selbstbeschränkungen hinsichtlich verwendeten Code-konstrukten
anzuraten. Insbesonders wenn man dem Synthese wie der TO selbst einräumt
wie "Schwarzer magie" gegenübersteht.
Gruß,
greg schrieb:> Für Designs, die intensiv Generics nutzen, sind Funktionen und Schleifen> häufig sogar absolut unerlässlich.
Genau dafür wird der besagte Anfänger diese Syntaxelemente dann deiner
Ansicht nach auch täglich brauchen. Oder wie?
Ich bleibe dabei: ein Anfänger sollte sein kleines Design erst mal ohne
solche Sachen auf der Hardware zum Laufen bringen. Und dann, wenn er
etwas Erfahrung hat, nachsehen, was man optimieren könnte und den Gewinn
aus solchen Sachen ziehen.
Aber niemals würde ich jemandem, der die Seitenwirkungen noch nicht
einschätzen kann, empfehlen, solche Sprachkonstrukte (die ich selber
ohne mit der Wimper zu zucken verwende) einzusetzen.
Das ist m.E. das Problem bei einem Buch: es sieht wegen der gleichen
Schrift irgendwie alles "gleichwertig" und "gleich wichtig" aus...