www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Mit std_logic_vector Mittelwert berechnen


Autor: Andreas B. (loopy83)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich habe folgende Frage:
Ich habe 1024, nacheinander einkommende 16bit Werte.
Diese werden zusammen mit einem valid-Signal im FPGA erzeugt.

Immer wenn das Valid Signal auf 1 geht weiß ich, dass ein neuer Wert 
bereit ist. Das geschieht genau 1024 mal.

Diese nacheinander kommenden Werte möchte ich nun in einer state_machine 
aufsummieren und am Ende, wenn alle 1024 Werte addiert worden sind, den 
Mittelwert bilden. Der Mittelwert wird dann in ein Fifo geschrieben. Am 
Ende soll der Fifo mit 2048 Mittelwerten gefüllt sein.

Nun sind die Daten vom Typ std_logic_vector.
use IEEE.NUMERIC_STD.ALL;
signal data_v : STD_LOGIC_VECTOR(15 downto 0);

Kann ich diese Daten nun einfach mit
signal data_i : integer range 0 to 2**16;

data_i <= to_integer(unsigned(data_v));

in sauber verrechenbare signale umwandeln und dann
signal summe_i : integer range 0 to 2**26;
signal summe_v : std_logic_vector(25 downto 0);

if valid = '1' then
  summe_i <= summe_i + data_num;
end if;

if counter = 1023 then
  summe_v <= to_unsigned(std_logic_vevtor(summe));
end if;

data_in_fifo <= summe_v(25 downto 10); --10 nach rechts shiften = /1024

Meine Überlegungen:
Ich wandle die Daten vom STD_LOGIC_VECTOR in integer um, summiere sie 
auf, wandle die Summe wieder zurück in STD_LOGIC_VECTOR, um dann das 
Ergebnis 10 Stellen nach rechts zu shiften, was ja /1024 (Anzahl der 
Werte) entspricht. Das alles schön getaktet in einer state_machine.

Meine Fragen:
- ist mein Vorgehen prinzipiell möglich und auch richtig beschrieben?
- muss ich für die cast- und konvertierungs-Vorgänge einen Takt 
einplanen?
- komme ich mit dem ganzen casten und konvertieren und rechnen mit drei 
Takten aus? Denn alle vier Takte kommt ein neuer Datenwert, der wieder 
mit aufsummiert werden soll, da sollte die state machine also wieder am 
Anfang stehen.

Ich wäre für Hinweise dankbar!

Vielen Dank!
Andi

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas B. schrieb:
> - ist mein Vorgehen prinzipiell möglich und auch richtig beschrieben?
Eigentlich schon, aber noch etwas zu umständlich...

> - muss ich für die cast- und konvertierungs-Vorgänge einen Takt
> einplanen?
Nein. Denn das wird trotzdem genau das gleich Bitmuster bleiben. Nur die 
Interpretation ist anders!

> - komme ich mit dem ganzen casten und konvertieren und rechnen mit drei
> Takten aus? Denn alle vier Takte kommt ein neuer Datenwert, der wieder
> mit aufsummiert werden soll, da sollte die state machine also wieder am
> Anfang stehen.
Um es kurz zu machen: du kannst Das alles in Integer rechnen und erst 
kurz vor der Übergabe konvertieren.

data_in_fifo <= summe_v(25 downto 10); --10 nach rechts shiften = /1024
Das ist unnötig, denn /1024 ist ein Abschneiden der letzten 10 Bits.
if counter = 1023 then
  summe_v <= std_logic_vector(to_unsigned(summe_1/1024, 16)); -- /1024 ist schon der "Shift"
end if;


BTW:
signal data_i : integer range 0 to 2**16;
signal summe_i : integer range 0 to 2**26;
Sollte das nicht besser 2**16-1 bzw. 2**26-1 heißen?

> summe_v <= to_unsigned(std_logic_vevtor(summe));
Das stimmt wohl auch noch was nicht ganz... ;-)

Autor: Andreas B. (loopy83)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank Lothar!

Lothar Miller schrieb:
> BTW:
>> signal data_i : integer range 0 to 2**16;
>> signal summe_i : integer range 0 to 2**26;
> Sollte das nicht besser 2**16-1 bzw. 2**26-1 heißen?

Naja, ich habe 16bit, das bedeutet 65536 Möglichkeiten.
Ich war davon ausgegangen, dass 2**16-1 nur 2^15 ist und das sind ja nur 
32768 Varianten. Aber die 2**x gibt ja immer 0 bis x an... also hast du 
wie immer recht: die -1 fehlt in beiden Fällen :)

Autor: berndl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
lass doch den ganzen integer-Kram weg und mache alles (bis auf 
In/Out=std_logic_vector) mit dem Typ 'unsigned'
* Du sparst dir Tipperei
* Du musst nicht auf den 32-bit (==+/-31bit) Integerwertebereich 
aufpassen

Also den input ala 'summe <= summe+unsigned(data);' verwursten, den 
output dann mit 'data_out <= std_logic_vector(summe(25 downto 10));'

'summe' ist hier ein 'unsigned (25 downto 0)'.

Autor: mac4ever (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas B. schrieb:
> Naja, ich habe 16bit, das bedeutet 65536 Möglichkeiten.
> Ich war davon ausgegangen, dass 2**16-1 nur 2^15 ist und das sind ja nur
> 32768 Varianten. Aber die 2**x gibt ja immer 0 bis x an... also hast du
> wie immer recht: die -1 fehlt in beiden Fällen :)

Na da rechnen wir nochmal nach ;)

2**16-1 /= 2**15 !!!
2**16-1 = 65535

Da das Zählen bei 0 beginnt (0..65535) ergeben sich demnach 65536 
Möglichkeiten.

integer range 0 to 2**16 belegt nämlich 17Bit und nicht 16!

Autor: Sym (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde auch mit unsigned rechnen, weil es oft einfacher ist und nicht 
auf 32 bit limitiert ist. Aber es erfolgt natürlich in der Simulation 
keine Überprüfung auf Under- und Overflows.
Zusammenzählen, um 10 bit nach rechts shiften, fertig.

Autor: Andreas B. (loopy83)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe die Idee mit unsigned nun umgesetzt, schauen wir mal, ob es auf 
Anhieb klappt.
when  stay =>
if valid = '1' then
  summe_u <= summe_u + unsigned(data);
  count_wr <= count_wr + 1;
  if count_wr = 1023 then
    cam_state <= next;
  else 
    cam_state3 <= stay;
  end if;
end if;

when next =>
  wr_en_fifo <= '1';
  din_fifo <= std_logic_vector(summe_u(25 downto 10));
  cam_state <= stay;
  summe_u <= (others => '0');

Vielen Dank ür die Hinweise und Hilfe!

Autor: Sym (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt soweit, aber beachte folgendes Problem: Wenn du ins FIFO 
schreibst, dann wird valid missachtet und ein Wert einfach ignoriert.

De facto ist diese Zustandsmaschine gar nicht nötig. din_fifo kannst du 
immer kombinarisch zuweisen und falls du 1023 erreicht hast, dann setze 
einfach das Write_enable des Fifos. Im nächsten Taktzyklus setze einfach 
die Summe auf data (Rücksetzung auf 0 + data).

Autor: Andreas B. (loopy83)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

danke für den Hinweis.
Das Valid kommt nur alle vier Takte.
Wenn es dann soweit ist, dass der Fifo beschrieben wird, kommt noch gar 
kein valid, das kommt erst wieder zwei Takte später und bis dahin liege 
ich wieder auf der Lauer :)

Vielen Dank!
Andi

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.