Forum: FPGA, VHDL & Co. Mit unterschiedlich langen Unsigned rechnen


von Gustl B. (-gb-)


Lesenswert?

Hallo,

ich habe einen ADC und will sobald der Wert davon über ein Schwellwert 
geht alle Werte aufsummieren bis der Wert wieder kleiner wie der 
Schwellwert wird. Also quasi die Fläche unter einem Peak bestimmen.

Ich bin mir sehr unsicher wie man das richtig rechnet in VHDL.

Der ADC ist 9-Bit Unsigned, der einstellbare Schwellwert ist auch 9-Bit 
Unsigned, und die Summe ist 16Bit Unsigned. Da ich keinen Überlauf haben 
will habe ich folgendes gemacht:
1
if ADC > Schwellwert and Summe /= "1111111111111111" then
2
   Summe <= Summe + ADC - Schwellwert;
3
end if;

- Schwellwert, weil ich nur die Fläche über dem Untergrund/Schwellwert 
haben will.

Ich habe auch schon ausprobiert:
1
if ADC > Schwellwert and Summe /= "1111111111111111" then
2
   Summe <= to_unsigned(to_integer(Summe) + to_integer(ADC) - to_integer(Schwellwert),16);
3
end if;

Den Fehler den ich sehe ist, dass die Summe die ich zum PC schicke, 
nicht größer wird wenn ich den analogen Peak größer einstelle, sondern 
trotz der Summe /= "1111111111111111" Bedingung weiterhin überläuft. 
Sprich wenn ich das analoge Signal groß mache bekomme ich irgendwann 
wieder kleine Summen.

Ist da ein Fehler in dem Code oder muss ich wo anders suchen?

Vielen Dank!

von Mike (Gast)


Lesenswert?

Das du bei einem Überlauf wieder unten ankommst ist das 
Standardverhalten in solchen Fällen. Das was du suchst nennt sich 
Sättigungsarithmetik und muss normalerweise speziell aktiviert werden. 
Du kannst ja mal schauen ob dein FPGA-Hersteller so etwas unterstützt. 
Hier für Altera:

http://www.altera.com/literature/ug/ug_lpm_alt_mfug.pdf

Damit dein Code funktioniert muss die Summe zufällig einmal den Wert 
"1111111111111111" annehmen. Wenn du nicht nur 1 aufaddierst wird es 
aber meistens nicht der Fall sein und es gibt dann den Überlauf. Am 
einfachsten wäre es die Berechnung auf 17 Bit zu erweitern und das 
höchste Bit auswerten.

von Gustl B. (-gb-)


Lesenswert?

Ah, danke, da war der Denkfehler von mir! Ja, ich baue in einem anderen 
Teil auch noch ein Spektrum, da wird immer nur 1 aufaddiert und da 
verwende ich das auch.

Edit:
Ich mach das jetzt mal so:
1
if ADC > Schwellwert then
2
   if "1111111111111111" - Summe >= ADC - Schwellwert then
3
      Summe <= to_unsigned(to_integer(Summe) + to_integer(ADC) - to_integer(Schwellwert),16);
4
   else
5
      Summe <= (others => '1');
6
   end if;
7
end if;

Vielen Dank!

: Bearbeitet durch User
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.