Guten Tag alle zusammen,
ich bitte, es zu entschuldigen, wenn das eine dumme Frage ist. Ich hatte
noch nicht allzuviel mit VHDL zu tun und frage daher jetzt lieber nach,
ob es dieses Feature gibt, bevor ich eine unnötig komplexe Lösung dafür
nutze.
Ich habe eine Komponente, die bereits einen Wert(MIN) per Generic
bekommt.
Mit diesem Wert wird innerhalb der Komponente ein Vergleich ausgeführt,
der ungefähr so aussieht:
1
IFxxx>=MINTHEN
Nun würde ich aber gerne nicht nur den Wert MIN per Generic zuweisen,
sondern auch den Vergleichsoperator (>, <, >=, <= oder =). Ist das per
Generic möglich?
Falls nicht, wie mache ich das am geschicktesten? Für jeden Operator
eine eigene Architecture schreiben und dann die passende beim
instanziieren auswählen?
Vielen Dank für eure Zeit
Sam
Du kannst einen Aufzählungstyp (in einem Package) definierten und den
verwenden als generic. z.B.
type vergleichsoperator is (kleiner, groesser, kleinergleich,
groessergleich, gleich)
und dann
entiry example is
generic(
operator : vergleichsoperator
);
....
Ok, das wäre dann schonmal weniger Overhead, als jedesmal eine neue
Architecture zu schreiben.
Sehe ich das richtig, dass ich dann nurnoch im Process einen Vergleich
für den Operator brauche und dann für jeden Operator nurnoch eine extra
Zeile brauche?
Und optimiert der Compiler das dann auch sauber?
Samuel C. schrieb:> Nun würde ich aber gerne nicht nur den Wert MIN per Generic zuweisen,> sondern auch den Vergleichsoperator (>, <, >=, <= oder =). Ist das per> Generic möglich?
Grundsätzlich schon; VHDL 2008 kann das:
1
libraryieee;
2
useieee.std_logic_1164.all;
3
4
entitycomparatoris
5
generic
6
(
7
functionop(x,y:integer)returnboolean
8
);
9
port
10
(
11
i1,i2:ininteger;
12
o:outboolean
13
);
14
endentitycomparator;
15
16
architecturesimofcomparatoris
17
begin
18
o<=op(i1,i2);
19
end;
20
21
libraryieee;
22
useieee.std_logic_1164.all;
23
useieee.numeric_std.all;
24
25
entitytbis
26
endentitytb;
27
28
architecturesimoftbis
29
signallt_i1,lt_i2:integer;
30
signalgt_i1,gt_i2:integer;
31
signallt_o,gt_o:boolean;
32
begin
33
34
i_lt_comparator:entitywork.comparator
35
genericmap
36
(
37
op=>"<"
38
)
39
portmap
40
(
41
i1=>lt_i1,
42
i2=>lt_i2,
43
o=>lt_o
44
);
45
46
i_gt_comparator:entitywork.comparator
47
genericmap
48
(
49
op=>">"
50
)
51
portmap
52
(
53
i1=>gt_i1,
54
i2=>gt_i2,
55
o=>gt_o
56
);
57
58
endarchitecturesim;
Die Sache hat nur einen Haken: es gibt nur ganz wenige
Implementierungen, die das auch unterstützen. Ob's bei dir geht, musst
Du ausprobieren oder nachlesen.
Samuel C. schrieb:> Falls nicht, wie mache ich das am geschicktesten?
Was ist denn das eigentliche Problem?
Denn wenn du noch nicht allzuviel mit VHDL zu tun hattest und etwas
brauchst, das sehr außergewöhnlich ist und wahrscheinlich nicht in
Hardware umgesetzt werden kann, dann könnte es leicht sein, dass du
eigentlich ganz was anderes willst...
Danke, den Ansatz werde ich auch mal testen :)
Im Prinzip hab ich oben schon so gut wie alles erklärt. Das Modul tut
nicht arg viel mehr als einen ermittelten Wert mit einem vorgegeben zu
vergleichen und mir dann '0' oder '1' auszugeben. Sowohl den Operator
als auch den zweiten Wert, will ich per Generic vorgeben.
Bis jetzt ist das mehr für mich zum experimentieren, da mich FPGAs schon
länger interessieren und ich endlich mal die Grundlagen lernen will.
Samuel C. schrieb:> Sowohl den Operator als auch den zweiten Wert will ich per Generic vorgeben.
Ja, das du es willst ist schon klar.
Meine Fragen zielten in die Richtung: Warum? Wofür? Weshalb?
Samuel C. schrieb:> Bis jetzt ist das mehr für mich zum experimentieren, da mich FPGAs schon> länger interessieren und ich endlich mal die Grundlagen lernen will.
Wie gesagt: für FPGAs kannst du sowas gar nicht brauchen. Denn welche 5%
des Sprachumfangs vom Synthesizer unterstützt werden, das findest du in
dessen Handbuch. Bestenfalls kannst du solche Konstrukte in einer TB
verwenden.
Und das ist dann auch das, was du beim Lernen vorneweg beachten musst:
Die Schnittmenge von VHDL mit FPGA ist wie gesagt bestenfalls 5%.
Wenn du VHDL lernen willst, dann kannst du dich mit Testbenches
austoben, da ist fast alles erlaubt.
Wenn du FPGA lernen willst, dann musst du das Subset von VHDL lernen,
das auch tatsächlich umgesetzt werden kann. So kann z.B. der Synthesizer
nicht mal ein simples "wait for" umsetzen. Selbst das "wait until
rising_edge()" geht erst seit knapp 10 Jahren.
Dagegen hat ein FPGA aber auch Komponenten (Taktgeneratoren, Speicher,
Kommunikationsbausteine, IO-Ports, ...) die du nicht mit VHDL
beschreiben, sondern bestenfalls über VHDL instatiieren kannst.
Lothar M. schrieb:> Ja, das du es willst ist schon klar.> Meine Fragen zielten in die Richtung: Warum? Wofür? Weshalb?
Um zu lernen und ein Gefühl für die Sprache und ihre Features zu
bekommen.
Lothar M. schrieb:> Wie gesagt: für FPGAs kannst du sowas gar nicht brauchen. Denn welche 5%> des Sprachumfangs vom Synthesizer unterstützt werden, das findest du in> dessen Handbuch. Bestenfalls kannst du solche Konstrukte in einer TB> verwenden.>> Und das ist dann auch das, was du beim Lernen vorneweg beachten musst:> Die Schnittmenge von VHDL mit FPGA ist wie gesagt bestenfalls 5%.> Wenn du VHDL lernen willst, dann kannst du dich mit Testbenches> austoben, da ist fast alles erlaubt.> Wenn du FPGA lernen willst, dann musst du das Subset von VHDL lernen,> das auch tatsächlich umgesetzt werden kann. So kann z.B. der Synthesizer> nicht mal ein simples "wait for" umsetzen. Selbst das "wait until> rising_edge()" geht erst seit knapp 10 Jahren.> Dagegen hat ein FPGA aber auch Komponenten (Taktgeneratoren, Speicher,> Kommunikationsbausteine, IO-Ports, ...) die du nicht mit VHDL> beschreiben, sondern bestenfalls über VHDL instatiieren kannst.
Das ist mir bewusst. Derzeit nutze ich auch nur einen Simulator, will
jedoch darauf achten, dass ich schon jetzt nur synthetisierbaren Code
schreibe (abgesehen von dem, was ich in der Simulation für Input/Output
benutze).
Ich habe das jetzt mal folgendermaßen geschrieben und werde das morgen
dann mal durch den Simulator schicken. Dann sieht man weiter.
Samuel C. schrieb:> Ich habe das jetzt mal folgendermaßen geschrieben
Das eigentlich eine simple ALU, die nur Vergleichsoperatoren handhabt.
Es ergibt im Prinzip einen Multiplexer und ist damit auch
synthetisierbar. Wenn der Operator per Generic übergeben wird, schmeißt
der Synthesizer die unnötigen Pfade raus.
> WHEN OTHERS =>
Das solltest du nicht machen, wenn dein "Operandentyp" so definiert ist,
dass du da eigentlich keine "übrigen" Fälle hast. Denn in deinem Fall
ist damit ja ausschließlich als "letzter übriger" Fall das "eq" gemeint.
Lothar M. schrieb:> Wie gesagt: für FPGAs kannst du sowas gar nicht brauchen. Denn welche 5%> des Sprachumfangs vom Synthesizer unterstützt werden, das findest du in> dessen Handbuch. Bestenfalls kannst du solche Konstrukte in einer TB> verwenden.
Ich jedenfalls (und manch anderer sicher auch) könnte so was durchaus
hin und wieder gebrauchen, das Problem ist halt, dass es nicht
unterstützt wird (auch liesse sich das durchaus synthesisieren, wenn man
nur wollte).
Wird es nicht unterstützt, weil es keiner nutzt (bzw. danach fragt) oder
nutzt es keiner, weil es nicht unterstützt wird?
VHDL 2008 wird dieses Jahr Zehn und bringt m.E. eine ganze Menge an
Funktionalität mit, die (auch) FPGA-Designern das Leben deutlich
leichter machen könnte. Da darf man als Entwickler - finde ich -
gegenüber den Herstellern schon ein wenig anspruchsvoller sein und eine
vollständigerere Implementierung einfordern.
Markus F. schrieb:> Wird es nicht unterstützt, weil es keiner nutzt (bzw. danach fragt)
Das ist hier in diesem Fall sicher auch ein Grund.
> oder nutzt es keiner, weil es nicht unterstützt wird?
Die zwingende Konsequenz... ;-)
> auch liesse sich das durchaus synthesisieren
Das wäre beim Konstrukt oben sicher einen Versuch wert. Aber ich wurde
schon einige Male unangenehm überrascht. Besonders auch bei Sachen, die
dann der eine Synthesizer konnte und der andere nicht. Da findet man
sich dann schnell beim kleinsten gemeinsamen Nenner... :-/
Dass ich hier ein "WHEN OTHERS" nutze ist vermutlich meiner bisher
weitgehend auf imperative Sprachen begrenzten Erfahrung zurückzuführen.
Auch wenn eine solche Verwendung da vermutlich ebenfalls Geschmackssache
ist.
Gibt es denn konkrete Gründe dagegen oder gehört es einfach nicht zum
"guten Ton"? Ich lasse mich da gerne belehren :)
Nichtsdestotrotz danke ich euch schonmal für eure Hilfe. Damit sollte
ich erstmal weiterkommen.
Samuel C. schrieb:> Gibt es denn konkrete Gründe dagegen
Nein, hier nicht (obwohl ich nicht weiß, ob der Typ von OP nicht auch
noch weitere Mitglieder hat, die dann zusammengefasst werden sollen...)
> oder gehört es einfach nicht zum "guten Ton"?
Das 100%ig.
Denn mal angenommen, ich muss deinen Code mal warten oder erweitern.
Dann stolpere ich über solche Sachen und denke mir: habe ich da jetzt
was übersehen?
Oder hat der ursprüngliche Entwickler da was übersehen?
Und wo wir gerade so über das when others diskutieren einen Link dazu:
http://www.lothar-miller.de/s9y/categories/25-when-others
Samuel C. schrieb:> Dass ich hier ein "WHEN OTHERS" nutze ist vermutlich meiner bisher> weitgehend auf imperative Sprachen begrenzten Erfahrung zurückzuführen.> Auch wenn eine solche Verwendung da vermutlich ebenfalls Geschmackssache> ist.>> Gibt es denn konkrete Gründe dagegen oder gehört es einfach nicht zum> "guten Ton"? Ich lasse mich da gerne belehren :)
wenn Du bei diesem case-Statement automatisch an "Multiplexer" denkst
("es gehen genau vier Drähte rein und genau einer kommt raus"), dann bin
ich auch der Ansicht, dass man das "others" weglassen sollte.
Fast genau dasselbe case-Statement kann aber auch "state machine"
bedeuten. Und da kann es dann sein (je nachdem, was Du eingestellt
hast", z.B. one-hot encoding), dass dein Aufzählungstyp schlimmstenfalls
auch andere Werte annehmen kann/könnte. U.U. macht dann "when others"
wieder Sinn. Vielleicht hast Du aber deine Synthese sogar so
eingestellt, dass sie eine "safe" state-machine erzeugt (die sich bei
fehlerhaften Werten "selbstständig rettet"), dann wär's wieder unpassend
;)
Markus F. schrieb:> Vielleicht hast Du aber deine Synthese sogar so eingestellt, dass sie> eine "safe" state-machine erzeugt (die sich bei fehlerhaften Werten> "selbstständig rettet"), dann wär's wieder unpassend ;)
Die meisten der Maßnahmen in Richtung "amoklaufende FSM abfangen"
basieren darauf, daß wieder mal einer nicht aufgepasst und asynchrone
Signale auf seine FSM losgelassen hat.
Lothar M. schrieb:> Markus F. schrieb:>> Vielleicht hast Du aber deine Synthese sogar so eingestellt, dass sie>> eine "safe" state-machine erzeugt (die sich bei fehlerhaften Werten>> "selbstständig rettet"), dann wär's wieder unpassend ;)> Die meisten der Maßnahmen in Richtung "amoklaufende FSM abfangen"> basieren darauf, daß wieder mal einer nicht aufgepasst und asynchrone> Signale auf seine FSM losgelassen hat.
Klar.
Scheint aber wohl so oft vorzukommen, dass (zumindest) Quartus dafür
extra ein "syn_encoding" "safe"-Attribut vorgesehen hat, das automatisch
"Fallschirm-Logik" dafür erzeugt (mit der Dokumentation, das eigene
Versuche, so was zu tun, sowieso gnadenlos wegoptimiert würden).
Vielen Dank für den Link. Ich werde mir auch deine anderen Artikel genau
anschauen.
Ja, ich sehe ein, dass es durchaus nicht ganz sauber ist, einen genau
definierten Zustand durch ein "WHEN OTHERS" zu detektieren. Ich werde
das mal auf "WHEN eq" ändern.