Forum: FPGA, VHDL & Co. VHDL Operator als Generic


von Samuel C. (neoexacun)


Lesenswert?

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
IF xxx >= MIN THEN

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

von user (Gast)


Lesenswert?

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
   );
....

von Samuel C. (neoexacun)


Lesenswert?

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?

von Markus F. (mfro)


Lesenswert?

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
library ieee;
2
use ieee.std_logic_1164.all;
3
4
entity comparator is
5
    generic 
6
    (
7
        function op(x, y : integer) return boolean
8
    );
9
    port
10
    (
11
        i1, i2  : in integer;
12
        o       : out boolean
13
    );
14
end entity comparator;
15
16
architecture sim of comparator is
17
begin
18
    o <= op(i1, i2);
19
end;
20
21
library ieee;
22
use ieee.std_logic_1164.all;
23
use ieee.numeric_std.all;
24
25
entity tb is
26
end entity tb;
27
28
architecture sim of tb is
29
    signal lt_i1, lt_i2         : integer;
30
    signal gt_i1, gt_i2         : integer;
31
    signal lt_o, gt_o           : boolean;
32
begin
33
34
    i_lt_comparator : entity work.comparator
35
        generic map
36
        (
37
            op => "<"
38
        )
39
        port map
40
        (
41
            i1 => lt_i1,
42
            i2 => lt_i2,
43
            o => lt_o
44
        );
45
46
    i_gt_comparator : entity work.comparator
47
        generic map
48
        (
49
            op => ">"
50
        )
51
        port map
52
        (
53
            i1 => gt_i1,
54
            i2 => gt_i2,
55
            o => gt_o
56
        );
57
58
end architecture sim;

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.

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


Lesenswert?

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...

: Bearbeitet durch Moderator
von Samuel C. (neoexacun)


Lesenswert?

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.

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


Lesenswert?

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.

: Bearbeitet durch Moderator
von Samuel C. (neoexacun)


Lesenswert?

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.
1
PROCESS (INPUT) IS
2
BEGIN
3
  CASE OP IS
4
    WHEN gt =>     OUTPUT <= '1' WHEN INPUT >  VAL ELSE '0';
5
    WHEN ge =>     OUTPUT <= '1' WHEN INPUT >= VAL ELSE '0';
6
    WHEN lt =>     OUTPUT <= '1' WHEN INPUT <  VAL ELSE '0';
7
    WHEN le =>     OUTPUT <= '1' WHEN INPUT <= VAL ELSE '0';
8
    WHEN OTHERS => OUTPUT <= '1' WHEN INPUT =  VAL ELSE '0';
9
  END CASE;
10
END PROCESS;

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


Lesenswert?

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.

von Markus F. (mfro)


Lesenswert?

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.

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


Lesenswert?

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... :-/

von Samuel C. (neoexacun)


Lesenswert?

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.

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


Lesenswert?

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

: Bearbeitet durch Moderator
von Markus F. (mfro)


Lesenswert?

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 
;)

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


Lesenswert?

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.

von Markus F. (mfro)


Lesenswert?

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).

von Samuel C. (neoexacun)


Lesenswert?

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.

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.