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


von Andreas B. (loopy83)


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.
1
use IEEE.NUMERIC_STD.ALL;
2
signal data_v : STD_LOGIC_VECTOR(15 downto 0);

Kann ich diese Daten nun einfach mit
1
signal data_i : integer range 0 to 2**16;
2
3
data_i <= to_integer(unsigned(data_v));

in sauber verrechenbare signale umwandeln und dann
1
signal summe_i : integer range 0 to 2**26;
2
signal summe_v : std_logic_vector(25 downto 0);
3
4
if valid = '1' then
5
  summe_i <= summe_i + data_num;
6
end if;
7
8
if counter = 1023 then
9
  summe_v <= to_unsigned(std_logic_vevtor(summe));
10
end if;
11
12
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

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


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.

1
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.
1
if counter = 1023 then
2
  summe_v <= std_logic_vector(to_unsigned(summe_1/1024, 16)); -- /1024 ist schon der "Shift"
3
end if;


BTW:
1
signal data_i : integer range 0 to 2**16;
2
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... ;-)

von Andreas B. (loopy83)


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 :)

von berndl (Gast)


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)'.

von mac4ever (Gast)


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!

von Sym (Gast)


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.

von Andreas B. (loopy83)


Lesenswert?

Ich habe die Idee mit unsigned nun umgesetzt, schauen wir mal, ob es auf 
Anhieb klappt.
1
when  stay =>
2
if valid = '1' then
3
  summe_u <= summe_u + unsigned(data);
4
  count_wr <= count_wr + 1;
5
  if count_wr = 1023 then
6
    cam_state <= next;
7
  else 
8
    cam_state3 <= stay;
9
  end if;
10
end if;
11
12
when next =>
13
  wr_en_fifo <= '1';
14
  din_fifo <= std_logic_vector(summe_u(25 downto 10));
15
  cam_state <= stay;
16
  summe_u <= (others => '0');

Vielen Dank ür die Hinweise und Hilfe!

von Sym (Gast)


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).

von Andreas B. (loopy83)


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

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.