Forum: FPGA, VHDL & Co. STD_LOGIC_VECTOR auf Überlauf überprüfen


von Tom (Gast)


Lesenswert?

Guten Morgen liebes Forum,

ich möchte gerne einen 32 Bit Vector auf einen Überlauf überprüfen. Wenn 
der Wert alle 32 Bit eine 1 hat oder überläuft, soll ein Fehlersignal 
ausgegeben werden.

Um dieses Problem zu detektieren, muss ich dafür den 32 Bit Vektor 
vergrößern, sagen wir beispielsweise auf 35 Bit und überprüfen, ob das 
33. 34. und 35 Bit gesetzt sind, wenn ja, dann Überlauf, wenn nein, dann 
nehme ich die unteren 32 Bits und habe keinen Überlauf? Oder lässt sich 
das anders lösen?


Vielen Dank und schönen Sonntag,

Tom

von Florian P. (db1pf)


Lesenswert?

Hallo,

ein Überlauf kann nur nach einer math. Operation erfolgen. Wenn du z.B. 
zwei 32-Bit Vektoren addierst ist das Ergebnis ein 33-Bit Vector. Wenn 
du jetzt mit einem 32-Bit Vektor weiter rechnen willst, nimmst du 
einfach die unteren 32-Bit.
Zum prüfen ob ein Überlauf aufgetreten ist, prüfst du einfach das 32. 
Bit. Können nur positive Zahlen auftreten, genügt der Test ob das Bit 1 
ist. Wenn ja ist ein Überlauf aufgetreten. Vorsicht wenn die 
Eingangsvektoren auch negative Zahlen darstellen (zweierkomplement). Ich 
bin mir jetzt nicht 100% sicher, ab ich meine du musst dann prüfen ob 
das 32. und 31. Bit identisch sind. Wenn die Bits ungleich sind, ist ein 
Überlauf aufgetreten.


Grüße,
Florian

von Michael (Gast)


Lesenswert?

Tom schrieb:
> 33. 34. und 35 Bit gesetzt sind

wenn das 33., das 34. ODER das 35. gesetzt sind.

Mathematisch einfach X + (geplanter Additionswert) > Limit?

Der Vergleich der bits ist aber direkter formuliert das, was ma Ende 
auch bei rauskommt, zumindest wenn das Limit an der Grenze eines Werts 
von 2hoch n liegt.

von Tom (Gast)


Lesenswert?

Michael schrieb:
> wenn das 33., das 34. ODER das 35. gesetzt sind.

Ja, da hast Du natürlich recht.

Wie kann ich denn in VHDL einzelne Bits eines Vektors vergleichen?
1
signal test : STD_LOGIC_VECTOR (34 downto 0);
2
signal overload : STD_LOGIC := 0;
3
4
process(clk)
5
begin
6
  if test(34 downto 34) = '1' then
7
     overload <= '1';
8
  end if;
9
10
  if test(33 downto 33) = '1' then
11
     overload <= '1';
12
  end if;
13
14
  if test(32 downto 32) = '1' then
15
     overload <= '1';
16
  end if;
17
18
end process;

Könnte ich das so umsetzen?

von Michael (Gast)


Lesenswert?

Das nennt man hard wired or. Das ist Banane!  Wenn, dann bitte alles in 
ein IF und mit elsif , ausserdem "else  overloead <= '0'";


oder auf RTL Ebene

overload <= sig1 or sig2 or .... ;

von Sven P. (Gast)


Lesenswert?

Ich würde erstmal nachschauen, was überhaupt mit dem Vektor passiert. 
Rechnen mit STD_LOGIC_VECTOR ist ne saublöde Idee. Entweder 
SIGNED/UNSIGNED oder gleich die Integer-Typen synthetisieren.

Wenn z.B. immer nur inkrementiert wird (+1), reicht es, das nächsthöhere 
Bit zu prüfen.

An einzelne Bits kommst du mit Subskript heran, etwa VEKTOR(1) = '1'. 
Die kann man gleich allesamt verodern, VEKTOR(1) or VEKTOR(2) ..., oder 
schlicht invertiert nachgucken. Ein Oder zwischen den drei Bits ist 
dasselbe, wie ein invertiertes Und. Und das geht mit VEKTOR(3 downto 1) 
/= "000".

Wenn aber mehr addiert wird, könnte es umständlich werden. Das 
Einfachste wäre vermutlich, einen Core mit Carry-Ausgang zu nehmen, je 
nachdem, was du sonst noch vor hast.

von Tom (Gast)


Lesenswert?

Sven P. schrieb:
> Rechnen mit STD_LOGIC_VECTOR ist ne saublöde Idee.

Ich rechne auch nicht mit STD_LOGIC_VECTOREN. Ich habe den Eingang des 
Typs STD_LOGIC_VECTOR zuvor in TYP UNSIGNED umgewandelt und diese Werte 
dann aufsummiert und mit einem Indexwert an der Stelle jeweiligen 
multipliziert.

Dieses UNSIGNED Signal wandel ich nach Fertigstellung der Summation 
wieder in STD_LOGIC_VECTOR um und verbinde es mit einen EIngang einer 
Komponente , wo dieser Wert durch einen anderen Wert geteilt wird.

Dieser Vektor bzw. Dividend darf jedoch die Größte von 32 Bit nicht 
überschreiten. Deshalb möchte ich zuvor in der Summation überprüfen, 
dass dieser Wert auch nicht größer wird, ansonsten soll es eine 
Fehlerbit gesetzt werden.

Sven P. schrieb:
> An einzelne Bits kommst du mit Subskript heran

Sind diese Subscripts auch synthetisierbar?

Das würde bedeuten, dass ich in einer IF-Anweisung
test(34) = '1' or test(33) = '1' or test(32) = '1' überprüfen müsste?



Michael schrieb:
> Das nennt man hard wired or.

Ahh, ok. Was ist denn der Nachteil daran bzw. der Vorteil an ELSIF?

von dito (Gast)


Lesenswert?

Tom schrieb:
> mit einem Indexwert an der Stelle jeweiligen
> multipliziert.

Wenn der Multiplikator eine Potenz von zwei kein Problem (entspricht 
links-Shift), falls nicht wird eine Multiplikationseinheit auf dem FPGA 
gebraucht.

Tom schrieb:
> Sind diese Subscripts auch synthetisierbar?

Ja sind sie.

von dito (Gast)


Lesenswert?

Tom schrieb:
> Ahh, ok. Was ist denn der Nachteil daran bzw. der Vorteil an ELSIF?

Falls du nur im if-Zweig dem Signal einen Wert zuweist, dann wird ein 
Latch im FPGA synthetisiert. Und das willst du nicht...

von Tom (Gast)


Lesenswert?

dito schrieb:
> Wenn der Multiplikator eine Potenz von zwei kein Problem (entspricht
> links-Shift), falls nicht wird eine Multiplikationseinheit auf dem FPGA
> gebraucht.

Embedded Multiplier Blocks sind auf dem FPGA vorhanden. Ich 
multipliziere u.a. auch mit den Faktoren 1, 3, 5, 7 .....

Dies sieht folgendermaßen aus:
1
summe <= summe + unsigned(Wert1) * unsigned((zaehler sll 1)+1) + unsigned(Wert2) * unsigned (((zaehler sll 1) + 1)+1);

Die Multiplier Blocks werden doch automatisch bei der Synthese 
verwendet, sodass ich diese nicht manuell irgendwie manuell ansprechen 
muss, oder?

Die XST Synthese ist fehlerfrei.

von Tom (Gast)


Lesenswert?

dito schrieb:
> Falls du nur im if-Zweig dem Signal einen Wert zuweist, dann wird ein
> Latch im FPGA synthetisiert. Und das willst du nicht...

OK, danke für die Info. Das war mir auch noch nicht so bewusst. Auch 
wenn das jetzt nicht mehr primär mit der eigentlich Frage zu tun hat. 
Woran liegt das denn technisch genau? Latches sind ja pegelgesteuert, 
was bei Glitches zu Problemen führen kann. Woran liegt das, bzw, wie 
kann ich mir das vorstellen, das bei ELSIF eine Flankenerkennung 
eingesetzt (also Flip Flops) und bei einer Signalzuweisung nur im IF 
Teil die Signale pegelgesteuert sind?

von dito (Gast)


Lesenswert?

Tom schrieb:
> Embedded Multiplier Blocks sind auf dem FPGA vorhanden. Ich
> multipliziere u.a. auch mit den Faktoren 1, 3, 5, 7 .....

Bei solchen kleinen Zahlen wird wahrscheinlich noch nicht einmal eine 
Multipliziererkomponente instanziiert (es ist ja nur ein Shift und 
Addition, das wird als Schaltnetz implmementiert). Im Zweifel einfach 
mal in den Synthesebericht schauen.

Tom schrieb:
> Woran liegt das, bzw, wie
> kann ich mir das vorstellen, das bei ELSIF eine Flankenerkennung
> eingesetzt (also Flip Flops) und bei einer Signalzuweisung nur im IF
> Teil die Signale pegelgesteuert sind?

Nein, im if-Zweig werden die Signale auch mit der Flanke übernommen.

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


Lesenswert?

Tom schrieb:
> das bei ELSIF eine Flankenerkennung eingesetzt (also Flip Flops)
> und bei einer Signalzuweisung nur im IF Teil die Signale
> pegelgesteuert sind?
Du hast noch ein nachhaltig undefiniertes Bild von dem, was du mit einer 
bestimmten Hardwarebeschreibung erhalten wirst...   :-o

if und elsif ist erst mal genau das, was man auf Basis der 
englischen Übersetzung vermuten würde: eine Abfrage und eine 
Fallentscheidung. Ob da anschliessend was auf eine Flanke reagiert, 
hängt von dieser Abfrage ab: taucht da ein 'event auf (evtl. auch 
versteckt in einer Funktion), dann gibt das ein D-Flipflop.

dito schrieb:
> Nein, im if-Zweig werden die Signale auch mit der Flanke übernommen.
Nur, wenn diese Abfrage in einem getakteten Prozessteil steht...

Tom schrieb:
> signal test : STD_LOGIC_VECTOR (34 downto 0);
> signal overload : STD_LOGIC := 0;
>
> process(clk)
> begin
>   if test(34 downto 34) = '1' then
>      overload <= '1';
>   end if;
>
>   if test(33 downto 33) = '1' then
>      overload <= '1';
>   end if;
>
>   if test(32 downto 32) = '1' then
>      overload <= '1';
>   end if;
> end process;
>
> Könnte ich das so umsetzen?
Das ist, genau so wie es da steht, schlicht falsch!
Dieser Prozess ist gerade nicht auf clk sensitiv.

>   if test(34 downto 34) = '1' then
Das müsste richtigerweise so heißen, weil ja nur ein einzelnes Element 
des Vektors abgefragt wird:
>   if test(34) = '1' then

von Tom (Gast)


Lesenswert?

Lothar Miller schrieb:
> Dieser Prozess ist gerade nicht auf clk sensitiv

Das stimmt natürlich. So kann es nicht funktionieren.

Also wäre es so richtig:
1
 signal test : STD_LOGIC_VECTOR (34 downto 0);
2
 signal overload : STD_LOGIC := 0;
3
4
 process(clk)
5
 begin
6
     if rising_edge(clk) then     
7
        if test(34) = '1' then
8
           overload <= '0';
9
        else
10
           overload <= '1';
11
        end if;
12
13
        if test(33) = '1' then
14
          overload <= '0';
15
        else
16
           overload <= '1';
17
        end if;
18
19
        if test(32) = '1' then
20
          overload <= '0';
21
        else
22
           overload <= '1';
23
        end if;
24
    end if;
25
 end process;
Dieser Prozess (obige) wäre doch bis auf das fehlende elsif soweit 
richtig, oder?


Folgender Prozess wäre dann richtg?
1
 process(clk)
2
 begin
3
     if rising_edge(clk) then     
4
        if test(34) = '1' then
5
           overload <= '1';        
6
7
        elsif test(33) = '1' then
8
          overload <= '1';        
9
10
        elsif test(32) = '1' then
11
          overload <= '1';
12
        
13
        else
14
           overload <= '0';
15
        end if;
16
    end if;
17
 end process;

dito schrieb:


> Falls du nur im if-Zweig dem Signal einen Wert zuweist, dann wird ein
> Latch im FPGA synthetisiert.

Also wäre diese Aussage ja nicht zutreffend, wenn die if Anweisung in 
einem Prozess steht, welcher clk sensitiv ist, also in meinem Fall. Habe 
ich das richtig verstanden?



dito schrieb:
> Bei solchen kleinen Zahlen wird wahrscheinlich noch nicht einmal eine
> Multipliziererkomponente instanziiert

Der zaehler nimmt auch Werte > 2000 an

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


Lesenswert?

Tom schrieb:
> Folgender Prozess wäre dann richtg?
>  process(clk)
>  begin
>      if rising_edge(clk) then
Ja, aaaaber...

...er ist unnötigerweise getaktet und bringt dir damit einen Takt 
Latency ins Spiel.

Ich würde das als Prozess so schreiben:
1
 process(test)
2
 begin
3
     overload <= '0';
4
     if test(34)='1' or test(33)='1' or test(32)='1' then
5
        overload <= '1';
6
     end if;
7
 end process;

Oder eher gleich ganz ohne Prozess so:
1
   overload <= '1' when test(34)='1' or test(33)='1' or test(32)='1' else '0';

Oder eher gleich so:
1
   overload <= '0' when test(34 downto 32)="000" else '1';

von Tom (Gast)


Lesenswert?

Ja vielen Dank.

Lothar Miller schrieb:
> ...er ist unnötigerweise getaktet und bringt dir damit einen Takt
> Latency ins Spiel.

So werden also die Änderungen sofort übernommen und nicht erst mit der 
nächsten Taktflanke?

Lothar Miller schrieb:
> overload <= '0' when test(34 downto 32)="000" else '1';

Und es war auch richtig, dass man mehrere IF's ohne ELSIF vermeiden 
sollte, auch wenn sie in einem sensitiven clk Prozess vorkommen?

von Stachele (Gast)


Lesenswert?

>Und es war auch richtig, dass man mehrere IF's ohne ELSIF vermeiden
>sollte,

Ich glaube, das ist mittlerweile völlig egal, da für Vektor-Abfragen 
priorisierte IF-Bäume ohnehin vom Synthesetool aufgelöst werden.

Aber kannst du dir ja mal im RTL-View anschauen, was für einen 
Unterschied die verschiedenen Beschreibungen letztendlich ausmachen.

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


Lesenswert?

Tom schrieb:
> So werden also die Änderungen sofort übernommen und nicht erst mit der
> nächsten Taktflanke?
Naja, was heißt "sofort"?
Es ist einfach nur Kombinatorik mit irgendwelchen Laufzeiten 
(wahrscheinlich in allen Fällen die selbe), nur ist in deinem Fall 
hinter diese Kombinatorik noch ein Flipflop geschaltet...

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.