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
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
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.
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?
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 .... ;
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.
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?
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.
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...
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:
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.
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?
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.
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
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
signaltest:STD_LOGIC_VECTOR(34downto0);
2
signaloverload:STD_LOGIC:=0;
3
4
process(clk)
5
begin
6
ifrising_edge(clk)then
7
iftest(34)='1'then
8
overload<='0';
9
else
10
overload<='1';
11
endif;
12
13
iftest(33)='1'then
14
overload<='0';
15
else
16
overload<='1';
17
endif;
18
19
iftest(32)='1'then
20
overload<='0';
21
else
22
overload<='1';
23
endif;
24
endif;
25
endprocess;
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
ifrising_edge(clk)then
4
iftest(34)='1'then
5
overload<='1';
6
7
elsiftest(33)='1'then
8
overload<='1';
9
10
elsiftest(32)='1'then
11
overload<='1';
12
13
else
14
overload<='0';
15
endif;
16
endif;
17
endprocess;
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
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:
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?
>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.
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...