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


von VHDLneu (Gast)


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!

von VHDLneu (Gast)


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[];

von Analog OPA (Gast)


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.

von VHDLneu (Gast)


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?
1
DL(0) <= '1' when (((CS   = '1') and A(4 downto 0) = b"00000") and (JA(0) ='1'))
2
                   or     
3
                   ((A(6) = '1') and A(4 downto 0) = b"00000") and (DD(0) ='1')))
4
         else '0';
5
6
DL(1) <= '1' when (((CS   = '1') and A(4 downto 0) = b"00000") and (JA(1) ='1'))
7
                   or     
8
                   ((A(6) = '1') and A(4 downto 0) = b"00000") and (DD(1) ='1')))
9
         else '0';
10
11
DL(2) <= '1' when (((CS   = '1') and A(4 downto 0) = b"00000") and (JA(2) ='1'))
12
                   or     
13
                   ((A(6) = '1') and A(4 downto 0) = b"00000") and (DD(2) ='1')))
14
         else '0';
15
16
...

von Markus F. (mfro)


Lesenswert?

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

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

von VHDLneu (Gast)


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
1
DL[] = CS & (A[4..0] == H"00") & JA[] & DD[];

ließe sich als

1
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

von Markus F. (mfro)


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.

von Markus F. (mfro)


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:
1
    signal dl, dd, ja, a        : std_ulogic_vector(15 downto 0);
2
    signal cs                   : std_ulogic;
3
...
4
    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:
1
    function et(s : std_ulogic; w : integer) return std_ulogic_vector is
2
        variable sluv : std_ulogic_vector(w - 1 downto 0);
3
    begin
4
        sluv := (others => s);
5
        return sluv;
6
    end function et;
7
    
8
    function "and"(signal sulv : std_ulogic_vector; signal sul : std_ulogic) return std_ulogic_vector is
9
        variable esul       : std_ulogic_vector(sulv'length - 1 downto 0);
10
    begin
11
        esul := et(sul, esul'length);
12
        return esul and sulv;
13
    end function "and";
14
    
15
    function "and"(signal sulv : std_ulogic_vector; signal b : boolean) return std_ulogic_vector is
16
        variable sul : std_ulogic;
17
    begin
18
        if b = true then sul := '1'; else sul := '0'; end if;
19
        return et(sul, sulv'length) and sulv;
20
    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 ;)

von Markus F. (mfro)


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:
1
  
2
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:
1
    function "and"(sulv : std_ulogic_vector; sul : std_ulogic) return std_ulogic_vector is
2
...
3
    function "and"(sulv : std_ulogic_vector; b : boolean) return std_ulogic_vector is
4
...

: Bearbeitet durch User
von VHDLneu (Gast)


Lesenswert?

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

von VHDLneu (Gast)


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?

von Markus F. (mfro)


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:
1
std_ulogic_vector(resize(unsigned'("0"), 5))

von VHDLneu (Gast)


Lesenswert?

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

von Markus F. (mfro)


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

von Mor F. (morphel)


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

von Markus F. (mfro)


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

von U.G. L. (dlchnr)


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.

von Markus F. (mfro)


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

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.