mikrocontroller.net

Forum: FPGA, VHDL & Co. Wie in VHDL formulieren


Autor: VHDLneu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie kann ich eine Ausdruck wie den folgenden am besten von AHDL in VHDL 
umformulieren?

DL[] = CS & (A[4..0] == H"00") & JA[]
     # CS & (A[4..0] == H"00") & JB[]
     # A6                      & DD[];

Die Vektoren gehen von "15 downto 0" - muss ich tatsächlich 16 
Gleichungen schreiben?

Vielen Dank!

Autor: VHDLneu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry - jetzt hab' ich beim vereinfacehn des ursprünglichen Ausdrucks 
Nonsens erzeugt - deshalb noch weiter vereinfacht!

DL[] = CS & (A[4..0] == H"00") & JA[]
     # A6                      & DD[];

Autor: Analog OPA (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist wohl recht einfach zu entschlüsseln, was da beschrieben ist:

Wenn Bedingung JA erfüllt ist, gilt der erste Adressvergleich mit dem 
Chip Seletc ansonsten der Zweite.

Die für mich interessante Frage ist, was passiert, wenn beide 
Bedingungen erfüllt sind. Inklusives Oder oder Vorrang für Bedingung 1, 
weil sie vorne steht (wäre in VHDL soweit Ich weiss, dasselbe) oder 
braucht es ein exklusives Oder, weil die beiden Bedingungen wahr sein 
können, dann aber nichts passieren darf.

Autor: VHDLneu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hängt Dich bitte nicht an der Logik auf - ich habe einen 
funktionierenden AHDL-Ausdruck zusammengestutzt, so dass er nur noch die 
wesentlichen Elemente enthält, die ich in der Art für eine andere Sache 
benötige - soll heißen - links ein Vektor, rechts ein Vektor plus ein 
Adressfeld plus einzelne Signale. Und frage ist, ob ich tatsächich 16 
Gleichungen der folgenden Art schreiben muss, um gleiches auszudrücken?
DL(0) <= '1' when (((CS   = '1') and A(4 downto 0) = b"00000") and (JA(0) ='1'))
                   or     
                   ((A(6) = '1') and A(4 downto 0) = b"00000") and (DD(0) ='1')))
         else '0';

DL(1) <= '1' when (((CS   = '1') and A(4 downto 0) = b"00000") and (JA(1) ='1'))
                   or     
                   ((A(6) = '1') and A(4 downto 0) = b"00000") and (DD(1) ='1')))
         else '0';

DL(2) <= '1' when (((CS   = '1') and A(4 downto 0) = b"00000") and (JA(2) ='1'))
                   or     
                   ((A(6) = '1') and A(4 downto 0) = b"00000") and (DD(2) ='1')))
         else '0';

...

Autor: Markus F. (mfro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
VHDLneu schrieb:
> Und frage ist, ob ich tatsächich 16
> Gleichungen der folgenden Art schreiben muss, um gleiches auszudrücken?

Nö.
dl <= ja when cs = '1' and a(4 downto 0) = "000000" else
      dd when a6 else
      (others => '0');

Autor: VHDLneu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Variante hatte ich sogar auch schon auf dem Tisch und fälschlich als 
nicht übereinstimmend verworfen - letztlich ist es aber nicht unbedingt 
das, was ich gesucht habe, es sei denn, eine AHDL-Gleichung wie
DL[] = CS & (A[4..0] == H"00") & JA[] & DD[];

ließe sich als

dl <= ja and dd when cs = '1' and a(4 downto 0) = b"000000" else (others => '0');

schreiben?

Werde das gelegentlich mal prüfen, falls es niemand aus dem Stehgreif 
beantworten kann - im Moment komme ich mit der vorgeschlagenen Variante 
weiter - Danke

Autor: Markus F. (mfro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
VHDLneu schrieb:
> ließe sich als
>
> dl <= ja and dd when cs = '1' and a(4 downto 0) = b"000000" else (others
> => '0');
> schreiben?

freilich.

Autor: Markus F. (mfro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
VHDLneu schrieb:
> DL[] = CS & (A[4..0] == H"00") & JA[] & DD[];

das ist übrigens ein hübsches Beispiel dafür, was man in VHDL alles 
anstellen kann, wenn man die Möglichkeiten der Sprache nutzt.
Wenn Du die AHDL-Semantik (nahezu) 1:1 in VHDL haben möchtest (keine 
gute Idee, m.E., nur um zu zeigen wie und dass das geht), würdest Du 
erst mal das hier hinschreiben:
    signal dl, dd, ja, a        : std_ulogic_vector(15 downto 0);
    signal cs                   : std_ulogic;
...
    dl <= ja and dd and cs and (a(4 downto 0) = x"00000") ;

(obiges nur ein wenig umgestellt, um mir das Leben zu vereinfachen). 
Wenn man das so durch den Compiler jagt, hagelt's erst mal 
Fehlermeldungen. Logisch, woher soll der wissen, wie man ein std_ulogic 
oder ein boolean mit Vektoren verundet?

Die Lösung ist: wir bringen's ihm einfach bei:
    function et(s : std_ulogic; w : integer) return std_ulogic_vector is
        variable sluv : std_ulogic_vector(w - 1 downto 0);
    begin
        sluv := (others => s);
        return sluv;
    end function et;
    
    function "and"(signal sulv : std_ulogic_vector; signal sul : std_ulogic) return std_ulogic_vector is
        variable esul       : std_ulogic_vector(sulv'length - 1 downto 0);
    begin
        esul := et(sul, esul'length);
        return esul and sulv;
    end function "and";
    
    function "and"(signal sulv : std_ulogic_vector; signal b : boolean) return std_ulogic_vector is
        variable sul : std_ulogic;
    begin
        if b = true then sul := '1'; else sul := '0'; end if;
        return et(sul, sulv'length) and sulv;
    end function "and";


Wir brauchen eine Hilfsfunktion, die ein std_ulogic auf eine gegebene 
Vektorbreite in einen std_ulogic_vector erweitert und zwei 
AND-Operatorüberladungen, die mit unseren Operandentypen umgehen können.

Und schon kann VHDL - ohne dass wir an der Zuweisung noch irgendwas 
ändern müssten - AHDL-Semantik ;)

Autor: Markus F. (mfro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier muss ich noch was nachschieben, nachdem ich meine "Ergüsse" von 
oben spasseshalber durch den Simulator geschickt habe:

das Literal x"00000" muss auf die richtige Länge gebracht werden, sonst 
ergibt der Vergleich immer false:
  
dl <= ja and dd and cs and (a(4 downto 0) = 5x"00000") ;
(oder eben ein geeignetes Äquivalent, falls man kein VHDL 2008 benutzt).

und dann sind sich GHDL und ModelSim erstaunlich einig, was die 
Simulation angeht: sie compilieren den Code ohne Gemecker, schmieren 
aber beide in trauter Zweisamkeit an derselben Problematik ab (GHDL mit 
einem ADA-Laufzeitfehler, ModelSim mit einem 'Fatal Error'). Auch sind 
sie sich beide lustigerweise erstaunlich einig darüber, dass man den 
Anwender über den Grund ihrer Befindlichkeiten möglichst im Unklaren 
lassen sollte - keine verwertbare Fehlermeldung (wobei GHDL wenigstens 
noch andeutungsweise Hinweise auf eine Typ-Problematik ausspuckt).

Ein bisschen Rumprobieren zeigt, dass sie beide dasselbe Problem haben: 
sie kommen mit den signal-Parametern der überladenen and-Operationen 
nicht zurecht (warum, ist mir - noch - nicht wirklich klar, m.E. müsste 
das auch so funktionieren). Wenn man 'signal' jeweils weg lässt, 
funktioniert alles wie's soll. Die beiden Funktionen müssen also so 
aussehen:
    function "and"(sulv : std_ulogic_vector; sul : std_ulogic) return std_ulogic_vector is
...
    function "and"(sulv : std_ulogic_vector; b : boolean) return std_ulogic_vector is
...

: Bearbeitet durch User
Autor: VHDLneu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die weiteren Hinweise - das VHDL ein Operatorüberladung kennt, 
war bei mir noch gar nicht angekommen.

Autor: VHDLneu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus F. schrieb:
> 5x"00000") ;
> (oder eben ein geeignetes Äquivalent, falls man kein VHDL 2008 benutzt).

Sowas mag der Aldec nicht - leider, denn immer auf b"..." ausweichen zu 
müssen, wenn die Anzahl der Vektorelemente kein Viefaches von 4 ist, 
nervt - von daher würden "ein geeignetes Äquivalent" sehr interessieren?

Autor: Markus F. (mfro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
VHDLneu schrieb:
> Markus F. schrieb:
>> 5x"00000") ;
>> (oder eben ein geeignetes Äquivalent, falls man kein VHDL 2008 benutzt).
>
> Sowas mag der Aldec nicht - leider, denn immer auf b"..." ausweichen zu
> müssen, wenn die Anzahl der Vektorelemente kein Viefaches von 4 ist,
> nervt - von daher würden "ein geeignetes Äquivalent" sehr interessieren?

da sind die älteren VHDL-Standards leider ein wenig ungelenk. Das hier 
müsste funktionieren:
std_ulogic_vector(resize(unsigned'("0"), 5))

Autor: VHDLneu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na ja - Schreibarbeit erspart man sich da wohl nicht, das sieht 
diesbezüglich  eher kontrapoduktiv aus :-)

Autor: Markus F. (mfro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
VHDLneu schrieb:
> Na ja - Schreibarbeit erspart man sich da wohl nicht, das sieht
> diesbezüglich  eher kontrapoduktiv aus :-)

Das ist nicht die einzige Ecke, wo die "alten" VHDL-Versionen reichlich 
- äh - umständlich (um nicht zu sagen, verkorkst) sind. Darum verwende 
ich nur noch VHDL 2008. Quartus unterstützt diesen (mittlerweile 
immerhin fast zehn Jahre alten Standard) zwar nicht vollständig, aber 
für mich ausreichend.

Für mich nicht nachvollziehbar, dass die Hersteller diesbezüglich 
anscheinend nicht in die Pötte kommen ...

Autor: Mor Fel (morphel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
VHDLneu schrieb:
> Markus F. schrieb:
>> 5x"00000") ;
>> (oder eben ein geeignetes Äquivalent, falls man kein VHDL 2008 benutzt).
>
> Sowas mag der Aldec nicht - leider, denn immer auf b"..." ausweichen zu
> müssen, wenn die Anzahl der Vektorelemente kein Viefaches von 4 ist,
> nervt - von daher würden "ein geeignetes Äquivalent" sehr interessieren?

ich behelfe mir gelegentlich mit "0" & x"0", wenn es die Lesbarkeit 
erhöht, ist aber auch eher ein krückenhaftes Konstrukt...

Autor: Markus F. (mfro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mor F. schrieb:
> ich behelfe mir gelegentlich mit "0" & x"0", wenn es die Lesbarkeit
> erhöht, ist aber auch eher ein krückenhaftes Konstrukt...

Dass das
std_ulogic_vector(resize(unsigned'("0"), 5))

so "sperrig" ist, liegt ja nur daran, dass es kein resize() gibt, das 
ein BIT_VECTOR-Literal in einen std_ulogic_vector umwandeln könnte.

Aber das kann man ja ändern ...

Autor: U.G. L. (dlchnr)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus F. schrieb:
> Aber das kann man ja ändern ...

Guter Hinweis - werde wohl demnächst mal meine erste Funktion in VHDL 
schreiben, um dann dafür ein cs2ukv(5,"1A") oder ähnliches für dieses 
Problemchen einsetzen zu können.

Autor: Markus F. (mfro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
U.G. L. schrieb:
> Markus F. schrieb:
>> Aber das kann man ja ändern ...
>
> Guter Hinweis - werde wohl demnächst mal meine erste Funktion in VHDL
> schreiben, um dann dafür ein cs2ukv(5,"1A") oder ähnliches für dieses
> Problemchen einsetzen zu können.

Das kann ich dir abnehmen:

https://www.edaplayground.com/x/52Af

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.