Forum: FPGA, VHDL & Co. Kombinatorik einer Variable zuordnen


von Karl der Kerl (Gast)


Lesenswert?

Guten Abend,

eines vorweg: ich bin Einsteiger und deshalb noch ein wenig grün hinter 
den Ohren.
Folgende Problem: ich möchte in einem getakteten Prozess augrund einer 
eher kryptischen logischen Ausdrucks in folgendem Stil einen Ausgang 
setzen.
1
if(A = B - 1 or (A = 20 and B = 0)) then inc <= '1';
2
else inc <= '0';
3
end if;
Zusätzlich würde ich gerne (an andere Stelle im Prozess) etwas machen, 
das zusätzlich noch von einem Eingang abhängt im Stil:
1
if(A = B - 1 or (A = 20 and B = 0) and read = '1') then dec <= '1';
2
elsif(blabla) --usw.
3
end if;

Da die Signale A, B so gewählt sind, dass man sich darunter etwas 
vorstellen kann und die Bedingung etwas komplizierter ist, werden die 
Bedingungen sehr unleserlich und lange. Ich könnte mir Schreibarbeit 
sparen, indem ich die zweite Bedingung in die erste reinverschachtle, 
das wird aber auch kryptisch.
Meine Idee war Folgende: da die Bedinung
1
A = B - 1 or (A = 20 and B = 0)
sehr gut mit "speicher_voll" o.ä. beschrieben werden kann, ein Signal 
damit zu machen, doch weil es ein getakteter Prozess ist und ich einen 
Takt Verzögerung nicht will, stehe ich schon wieder am Berg.
Die zweite Idee war die Verwendung von einer Variablen. Doch da 
scheitert es an der Zuweisung des Logischen Ausdrucks:
1
begin
2
  process(clk)
3
  variable speicher_voll : STD_LOGIC;
4
  begin
5
    if(rising_edge(clk)) then
6
    speicher_voll := (A = B - 1 or (A = 20 and B = 0))
7
--usw.

Bin ich total auf dem Holzweg oder wie kann ich der Variable dieses 
Kombinatorik zuweisen? Der Fehler der auftaucht:

Type of speicher_voll is incompatible with type of or.


Vielen Dank für alle Tipps... & einen schönen Abend!

von daniel__m (Gast)


Lesenswert?

Karl der Kerl schrieb:
> Type of speicher_voll is incompatible with type of or.

hi,

hierfür eignen sich Variablen hervorragend, und hier ist die Verwendung 
auch richtig. Die Fehlermeldung ist der Schlüssel: einfach den Datentyp 
der Variable überdenken(es gibt auch andere als std_logic).

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


Lesenswert?

daniel__m schrieb:
> einfach den Datentyp der Variable überdenken
Und sich fragen: was soll den ein '=' Operator ausser true und false 
zurückgeben? Und welcher Datentyp kann true und false?
Und dran denken: in VHDL ist eine '1' etwas grundsätzlich anders als 
ein true, bzw. eine '0' komplett was anderes als ein false! Das wird 
nicht wie in C implizit gleichgesetzt oder per emun geregelt...

> (es gibt auch andere als std_logic).
Man kann auch für std_logic die Operatoren so ändern, dass sie wieder 
std_logic zurückgeben...

Karl der Kerl schrieb:
> Da die Signale A, B so gewählt sind, dass man sich darunter etwas
> vorstellen kann und die Bedingung etwas komplizierter ist, werden die
> Bedingungen sehr unleserlich und lange.
Und dadurch auch das Design langsam. Das ist dir schon auch klar?

> Bin ich total auf dem Holzweg
Ja, du programmierst VHDL wie C. Das ist der Holzweg.

> sehr gut mit "speicher_voll" o.ä. beschrieben werden kann, ein Signal
> damit zu machen, doch weil es ein getakteter Prozess ist und ich einen
> Takt Verzögerung nicht will
Du hast nicht verstanden, woher diese Latency kommt. Und auch nicht, wie 
die Verwendung einer Variablen diese Latency (augenscheinlich) umgeht.

Karl der Kerl schrieb:
> Meine Idee war Folgende: da die Bedinung A = B - 1 or (A = 20 and B = 0)
> sehr gut mit "speicher_voll" o.ä. beschrieben werden kann, ein Signal
> damit zu machen, doch weil es ein getakteter Prozess ist und ich einen
> Takt Verzögerung nicht will
Dann ermittle diesen Wert ausserhalb des Prozesses als ein Concurrent 
statement. Es ist mir klar, dass Softies lieber mit Prozessen arbeiten, 
weil die noch am ehesten "Schritt-für-Schritt" abgearbeitet werden, oder 
es wenigstens so aussieht. Nur: das trügt. Ich würde dieses Signal so 
erzeugen:
1
  signal speicher_voll : STD_LOGIC;
2
3
    speicher_voll <= '1' when (A = B - 1 or (A = 20 and B = 0)) else '0';
4
5
6
begin
7
  process(clk)
8
  begin
9
    if(rising_edge(clk)) then
10
      if(speicher_voll='1' and read = '1') then dec <= '1';
11
      elsif(blabla) --usw.
12
      end if;
13
--usw.
Voila: keinerlei Latency in der Abfrage...

von Karl der Kerl (Gast)


Lesenswert?

Vielen Dank für die sehr kompetenten und geschätzten Beiträge!
Ich schätze, ich habe die Lösung, ohne es allerdings ausprobiert zu 
haben: Ich muss noch eine Typkonvertierung machen, da STD_LOGIC eben 
mehr als nur '1' und '0' speichern kann ('Z', 'X', etc.).

Die Idee mit dem Nebenläufigen Kombinatorik ist mir auch erst in der 
Einschlafphase in den Sinn gekommen. Werde sie demnächst testen.

Folgende Frage dazu habe ich allerdings noch: und zwar zu der Latenz: 
weshalb ist die bei der Verwendung mit Variablen grösser? Meiner 
beschränkten Ansicht nach sind die ebenbürtig und beide gleich stark 
optimierbar: sie verwenden beide die gleichen Eingangsdaten und haben 
die selbe Auswirkung. Das würde doch heissen, dass von den Eingangsdaten 
zur Auswirkung letztendlich lediglich Kombinatorik ist, die, wenn gleich 
optimiert wird, genau gleich aussehen könnte. Wo ist mein Denkfehler?
Nicht dass das für meine einfachen Tests & Übungen irgend einen 
Unterschied machen würde, sondern lediglich, dass ich das ein bisschen 
besser verstehe. Denn wie Lothar bereits bemerkt hat, ist es doch eine 
grosse Umstellung von C zu VHDL. Aber wenn man in Zuständen denkt, hatte 
ich das Gefühl eigentlich ziemlich richtig zu denken und bereits 
intuitiv vieles richtig gemacht zu haben.

Danke nochmals & Gruss

von daniel__m (Gast)


Lesenswert?

Karl der Kerl schrieb:
> weshalb ist die bei der Verwendung mit Variablen grösser?

Ist sie nicht. Wie du schon richtig erkannt hast, ist die Logik dahinter 
identisch zur nebenläufigen Anweisung. Ich denke, es war gemeint, dass 
der Unterschied zwischen Variable und Signal nicht genau klar ist, so 
dass nicht klar ist/war warum im getakteten Process eine Variable keine 
Latenz erzeugt, ein Signal aber schon.

von Amateur (Gast)


Lesenswert?

Wenn möglich: Finger weg von Begriffen wie read, inc usw.

So lange Du den erlaubten Wertebereich nicht überschreitest, kannst Du 
einer Variablen jeden Wert zuweisen und diesen nach eigenem Gusto 
interpretieren.

Also:
5  == Feierabend
6  == HoseVoll
7  == GehtNicht
-1 == MoagINed

Auch ist es jederzeit möglich das Ergebnis eines komplexen Vergleichs, 
in einer, dann meist boolschen, Variablen zu Speichern. Macht zusammen 
mit einem aussagekräftigen Namen, einiges Übersichtlicher.

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


Lesenswert?

Amateur schrieb:
> Also:
> 5  == Feierabend
> 6  == HoseVoll
> 7  == GehtNicht
> -1 == MoagINed
Ich würde da einen eigenen vierwertigen Datentyp definieren...

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.