Forum: FPGA, VHDL & Co. Maximum suchen


von antonio23 (Gast)


Lesenswert?

Hallo,

ich weiß, das es schon mal eine Anfrage wegen der Suche nach einem 
Maximum gab, das was da behandelt wird ist auch nicht mein Problem.

Ich möchte auf einem komplexen Signal (signed, real/imag) das Maximum 
finden. Es handelt sich um 512 Werte, die nacheinander von der Funktion 
abgefragt werden. Da die Werte für jeden Takt geändert werden, sollte 
die FUnktion auch jeden Wert abgreifen können.

Dieses Maximum will ich dann speichern, also den jeweiligen Realteil und 
Imaginärteil.

Ich habe das auch schon mal probiert und einen Summenvektor definiert 
und außerhalb eines Proßesses die Vektoren addiert. Das funktioniert 
leider nur genau so lange, wie die Summe der beiden Vektoren (15 downto 
0 ) die Grenze nicht überscheiten.

Hat jemand da eine Idee, wie man das lösen kann???

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


Lesenswert?

antonio23 schrieb:
> Ich habe das auch schon mal probiert und einen Summenvektor definiert
> und außerhalb eines Proßesses die Vektoren addiert.
Es ist an sich ganz egal, wo da was addiert wird...

> wie die Summe der beiden Vektoren (15 downto 0 ) die Grenze nicht
> überscheiten.
Welche Grenze?
Was ist dein Problem?

von Andreas D. (Gast)


Lesenswert?

Das kommt eben ganz drauf was du als "Maximum" definiert.

Anders gefragt; Was ist für dich größer: 5+5i oder 5-5i?


Ansonsten noch ein anderer Vorschlag:
Verschiebe doch einfach die Werte des Realteils und den Imaginärteils in 
den positiven Bereich. Also einfach den Wert der Obergrenze aufaddieren. 
Wenn du dein Maximum gefunden hast, brauchst du die Werte dann einfach 
nur noch zurück verschieben.

von antonio23 (Gast)


Lesenswert?

Lothar Miller schrieb:
> Welche Grenze?
> Was ist dein Problem?

Wenn imaginärteil und realteil beide z. B. x"FFFF" sind, dann komme ich 
ja mit meinem Vektor für das Maximum (Amplitude <= imag + real) nicht 
mehr hin.

von antonio23 (Gast)


Lesenswert?

Andreas D. schrieb:
> Anders gefragt; Was ist für dich größer: 5+5i oder 5-5i?

Anhand der Werte die rein kommen, kann diese Konstellation nicht 
auftreten, es soll schon ein "klares" Maximum in den EIngangsdaten 
vorhanden sein

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


Lesenswert?

antonio23 schrieb:
> dann komme ich  ja mit meinem Vektor für das Maximum
> (Amplitude <= imag + real) nicht mehr hin.
Die Formel ist falsch!
Weil imag und real orthogonal zueinander stehen, müssen sie quadratisch 
addiert werden...

Seis drum: mach deine Vektoren zum Rechnen einfach breiter.
Mit so einem signed Vektor kannst du einfach resize() aufrufen, und 
fertig.

Also etwa so:
1
signal amplitude : signed(32 downto 0);
2
3
Amplitude <= resize(imag,33)*resize(imag,33) + resize(real,33)*resize(real,33);
Du brauchst allein zum Bestimmen des Maximums übrigens nicht mehr 
anschliessend die Wurzel ziehen...

von antonio23 (Gast)


Lesenswert?

Lothar Miller schrieb:
> Seis drum: mach deine Vektoren zum Rechnen einfach breiter.
> Mit so einem signed Vektor kannst du einfach resize() aufrufen, und
> fertig.

ah, so einen Befehl hatte ich gesucht.

Vielen Dank für die Hilfe

von blubb (Gast)


Lesenswert?

Er will damit drauf raus, dass Komplexe Zahlen nicht anordenbar sind. Du 
kannst wenn dann ein Maximum im Betrag feststellen. Und wenn du hier 
merkst, dass Du einen überlauf des Wertes sqrt(im(x)^2+re(x)^2) hast, 
dann musst Du halt einfach ne größere Variable nehmen.

von antonio23 (Gast)


Lesenswert?

blubb schrieb:
> Er will damit drauf raus, dass Komplexe Zahlen nicht anordenbar sind. Du
> kannst wenn dann ein Maximum im Betrag feststellen. Und wenn du hier
> merkst, dass Du einen überlauf des Wertes sqrt(im(x)^2+re(x)^2) hast,
> dann musst Du halt einfach ne größere Variable nehmen.

ja, das war mir klar, ich hatte nur probleme damit die Addition der 
Real- und Imaginärteile durchzuführen. Aber mit Resize sind dann alle 
Probleme gelöst

von antonio23 (Gast)


Lesenswert?

Lothar Miller schrieb:
> Amplitude <= resize(imag,33)*resize(imag,33) + resize(real,33)*resize(real,33);

hab die Sache jetzt eingefügt und entsprechend angepasst:


Amplitude <= resize(source_imag_input,33)*resize(source_imag_input,33) + 
resize(source_imag_input,33)*resize(source_imag_input,33);


bekomme aber jetzt fogende Fehlermeldungen:

ERROR:HDLParsers:808 - 
"C:/Users/Gensmantel/Documents/Xilinx/Maximum_01/Maximum_01/maximum_01.v 
hd"  Line 59. resize can not have such operands in this context.


hab folgende Libarys eingefügt:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;

source_imag_input ist ein in  STD_LOGIC_VECTOR(15 downto 0);
source_real_input ist ebenfalls ein in  STD_LOGIC_VECTOR(15 downto 0);

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


Lesenswert?

antonio23 schrieb:
> hab folgende Libarys eingefügt:
>
> library IEEE;
> use IEEE.std_logic_1164.all;
> use IEEE.std_logic_arith.all;
> use IEEE.std_logic_unsigned.all;
> use IEEE.numeric_std.all;
Ach schlags kaputt. Warum muß man jedem immer das selbe sagen?  :-/
Lies das: Beitrag "std_logic_vector zu integer"
Oder das: Beitrag "addition von std_logic"
Oder jeden anderen der 165534 Beiträge, in denen immer der selbe Fehler 
gemacht wird....

> Line 59. resize can not have such operands in this context.
>
> source_imag_input ist ein in  STD_LOGIC_VECTOR(15 downto 0);
> source_real_input ist ebenfalls ein in  STD_LOGIC_VECTOR(15 downto 0);
Ich meinte, vorhin erwähnt zu haben, dass resize() nur mit signed und 
unsigned Vektoren funktioniert. Das war im 
Beitrag "Re: Maximum suchen"

von antonio23 (Gast)


Angehängte Dateien:

Lesenswert?

Okay, I'm sorry. Bin noch nicht so bewandert im Umwandeln...

Hab aber immer noch ein Problem:

Hab jetzt folgenden Quellcode:
1
entity maximum_01 is
2
    Port (      clk: in STD_LOGIC;
3
                clk_enable: in STD_LOGIC;
4
                reset_n: in STD_LOGIC;
5
                source_imag_input : in  STD_LOGIC_VECTOR(15 downto 0);
6
                source_real_input : in  STD_LOGIC_VECTOR(15 downto 0);
7
                source_imag_output : out  STD_LOGIC_VECTOR(15 downto 0);
8
                source_real_output : out  STD_LOGIC_VECTOR(15 downto 0)
9
     );
10
end maximum_01;
11
12
architecture Behavioral of maximum_01 is
13
14
-- Deklaration der internen Signale
15
16
Signal Maximum_Wert_imag:          std_logic_vector (15 downto 0):=x"0000";
17
Signal Maximum_Wert_real:          std_logic_vector (15 downto 0):=x"0000";
18
Signal Maximum_Wert_Amplitude:     signed(33 downto 0) ;
19
Signal Amplitude :               signed(33 downto 0) ;
20
21
22
23
24
begin
25
26
-- Berechnung der Amplitude
27
28
Amplitude <= resize(signed(source_imag_input),17)*resize(signed(source_imag_input),17) + resize(signed(source_imag_input),17)*resize(signed(source_imag_input),17);
29
30
31
-- Abfrage und Zuweisung der Maximalwerte innerhalb eines Prozesses
32
33
Maximum_Berechnung: process (clk, reset_n, clk_enable) -- Begin der Maximum Berechnung
34
35
begin
36
     if reset_n='0' then                                -- asynchrones Rücksetzen
37
                    Maximum_Wert_real <= x"0000";
38
                    Maximum_Wert_imag <= x"0000";
39
     elsif clk'event and clk='1' then                   -- Synchrone Übernahme der Daten
40
           if clk_enable = '1' then
41
                     if (Amplitude) > (Maximum_Wert_Amplitude) then
42
                     Maximum_Wert_real      <= source_real_input;
43
                     Maximum_Wert_imag      <= source_imag_input;
44
                     end if;
45
           end if;
46
     end if;
47
48
end process Maximum_Berechnung;
49
50
51
-- Zuweisung der internen Signale auf die externen Signale
52
source_imag_output <= Maximum_Wert_imag;
53
source_real_output <= Maximum_Wert_real;
54
55
end Behavioral;

Beim Kompilieren bekomme ich eine Warnung:

WARNING:Xst:653 - Signal <Maximum_Wert_Amplitude> is used but never 
assigned. This sourceless signal will be automatically connected to 
value 0000000000000000000000000000000000.

und in der Simulation mit Modelsim werden die Ausgangsvektoren nicht 
aktualisiert. Siehe Bild.

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


Lesenswert?

antonio23 schrieb:
> Beim Kompilieren bekomme ich eine Warnung:
Setz Maximum_Wert_Amplitude mal beim Reset oder bei der Definition auf 
einen definierten Wert...
So wie bei denen:
Signal Maximum_Wert_real:  std_logic_vector (15 downto 0):=x"0000";

von antonio23 (Gast)


Angehängte Dateien:

Lesenswert?

Hab den Quelltext jetzt angepasst:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
6
entity maximum_01 is
7
    Port (      clk: in STD_LOGIC;
8
                clk_enable: in STD_LOGIC;
9
                reset_n: in STD_LOGIC;
10
                source_imag_input : in  STD_LOGIC_VECTOR(15 downto 0);
11
                source_real_input : in  STD_LOGIC_VECTOR(15 downto 0);
12
                source_imag_output : out  STD_LOGIC_VECTOR(15 downto 0);
13
                source_real_output : out  STD_LOGIC_VECTOR(15 downto 0)
14
     );
15
end maximum_01;
16
17
architecture Behavioral of maximum_01 is
18
19
-- Deklaration der internen Signale
20
21
Signal Maximum_Wert_imag:          std_logic_vector (15 downto 0):=x"0000";
22
Signal Maximum_Wert_real:          std_logic_vector (15 downto 0):=x"0000";
23
Signal Maximum_Wert_Amplitude:     signed(33 downto 0) ;
24
Signal Amplitude :               signed(33 downto 0) ;
25
26
27
begin
28
29
-- Berechnung der Amplitude
30
31
Amplitude <= resize(signed(source_imag_input),17)*resize(signed(source_imag_input),17) + resize(signed(source_imag_input),17)*resize(signed(source_imag_input),17);
32
33
34
-- Abfrage und Zuweisung der Maximalwerte innerhalb eines Prozesses
35
36
Maximum_Berechnung: process (clk, reset_n, clk_enable) -- Begin der Maximum Berechnung
37
38
begin
39
     if reset_n='0' then                                -- asynchrones Rücksetzen
40
                    Maximum_Wert_real <= x"0000";
41
                    Maximum_Wert_imag <= x"0000";
42
              Maximum_Wert_Amplitude <= "0000000000000000000000000000000000";
43
     elsif clk'event and clk='1' then                   -- Synchrone Übernahme der Daten
44
           if clk_enable = '1' then
45
                     if (Amplitude) > (Maximum_Wert_Amplitude) then
46
                     Maximum_Wert_real      <= source_real_input;
47
                     Maximum_Wert_imag      <= source_imag_input;
48
                     end if;
49
           end if;
50
     end if;
51
52
end process Maximum_Berechnung;
53
54
55
-- Zuweisung der internen Signale auf die externen Signale
56
source_imag_output <= Maximum_Wert_imag;
57
source_real_output <= Maximum_Wert_real;
58
59
end Behavioral;

In Modelsim werden aber immer die aktuellen Werte übernommen und nicht 
die Maximalen gespeichert (siehe Abbildung)...

von T. F. (sar)


Lesenswert?

Du solltest noch "Maximum_Wert_Amplitude" aktualisieren

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


Lesenswert?

antonio23 schrieb:
> In Modelsim werden aber immer die aktuellen Werte übernommen und nicht
> die Maximalen gespeichert (siehe Abbildung)...
Im Ernst: ein klein wenig Mitdenken könnte auch nicht schaden...

Du kannst dir die internen Signale eines Moduls im Modesim auch anzeigen 
lassen. Dann würdest du sofort sehen, dass Maximum_Wert_Amplitude immer 
0 bleibt...
Siehe den Beitrag "Modelsim: locale Signale anzeigen"

von antonio23 (Gast)


Lesenswert?

Stefan S. schrieb:
> Du solltest noch "Maximum_Wert_Amplitude" aktualisieren

ach, shit... Hab so oft an dem Quelltext zwischenzeitig geändert, da hab 
ich das glatt vergessen wieder mit rein zu nehmen... Jetzt funktioniert 
es.

THX

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.