Forum: FPGA, VHDL & Co. Absolutwert von parallelen Daten


von Mark W. (kram) Benutzerseite


Lesenswert?

Hallo,

ich moechte in VHDL eine digitalen Gleichrichter bauen. Also Daten 
kommen vom ADC und ich moechte negative Werte in Positive umwandeln. 
Falls es wichtig ist, die Daten wurden  mit 40MSPS abgetastet.
Dazu habe ich mir erstmal einen Zaehler gebaut, der auch soweit 
funktionierte. Ich konnte die Werte an den Pins abgreifen.
Nun wollte ich ein Modul zwischen den Ausgaengen des Zaehlers und den 
Ausgaengen des FPGAs schalten, was nicht funktioniert. Ich denke, dass 
das was mit den Signaltypen zu tun hat, weiss aber nicht genau was.

Hier ads Gleichrichtermodul:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
entity rect is
6
  port
7
    (
8
      A : in signed(15 downto 0);
9
      Y2 : out signed(15 downto 0)
10
    );
11
end rect;
12
13
architecture BEHAVIOR of rect is
14
15
begin
16
17
process (A) is
18
19
begin
20
    Y2 <= abs(A);
21
end process;
22
23
end BEHAVIOR;
Und hier das Toplevelmodul:
1
library IEEE;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_unsigned.all;
4
use ieee.numeric_std.all;
5
6
entity TOP is
7
  port(
8
    CLK    : in std_logic;
9
    CNTOUT : out std_logic_vector(15 downto 0)
10
    );
11
end TOP;
12
13
architecture STRUCTURE of TOP is
14
15
signal S : std_logic_vector(15 downto 0);
16
17
component COUNTER
18
  port
19
    (
20
    CLK : in std_logic;
21
    Y1 : out std_logic_vector(15 downto 0)
22
    );
23
end component;
24
25
component rect
26
port
27
    (
28
      A : in signed(15 downto 0);
29
      Y2 : out signed(15 downto 0)
30
    );
31
end component;
32
33
begin
34
COUNTER1 : COUNTER port map (CLK => CLK, Y1 => S);
35
rect   : rect port map (std_logic_vector(A) => S, std_logic_vector(Y2) => CNTOUT);
36
37
end STRUCTURE;

Fehlermeldungen sind Folgende:
ERROR - 
C:/AllMyFiles/LatticeDiamondProjects/Counter_Test02/TOP.vhd(35,1-35,5) 
(VHDL-1223) rect is already declared in this region
ERROR - 
C:/AllMyFiles/LatticeDiamondProjects/Counter_Test02/TOP.vhd(35,24-35,48) 
(VHDL-1340) input designator a cannot contain a formal type-conversion
ERROR - 
C:/AllMyFiles/LatticeDiamondProjects/Counter_Test02/TOP.vhd(13,1-37,15) 
(VHDL-1284) unit structure ignored due to previous errors

von VHDL-Polizei (Gast)


Lesenswert?

Instanzennamen ändern!

von Lern Instructor (Gast)


Lesenswert?

Typumwandlungen in der numeric_std nachschlagen:
https://www.mimuw.edu.pl/~marpe/pul/card_1164.pdf

Typen von signalen innerhalb architecture nach Typ ausgangsport 
componenten wählen und Konvertierungen möglichst nicht in der Portmap 
und wenn doch, dann Syntax entsprechend VHDL-Lehrbuch resp. Language 
refrence manual:
https://www.ics.uci.edu/~jmoorkan/vhdlref/compinst.html

Sich nicht beim coding style durch Tippfaulheit selbst ins Knie 
schießen, sondern Einrückungen und identifiers mit Vernunft wählen.
https://wiki.ntb.ch/infoportal/_media/software/programmierrichtlinien/vhdl_guidelines_deutsch.pdf
1
architecture struct of top is
2
3
signal sig_cnt_16b  : std_logic_vector(15 downto 0);
4
signal sig_cnt_s16b : signed(15 downto 0);
5
6
--...
7
begin
8
 I_CNT_1 : counter port map (
9
  CLK => clk, 
10
  Y1  => sig_cnt_16b);
11
12
  I_RECT_1 : rectifier port map (
13
   A  => signed(sig_cnt_16b), 
14
   Y2 => Y2);
15
16
   cntout <= std_logic_vector(sig_cnt_s16b);
17
18
end struct;


Und im Forum statt textuelle Code-Kopien, sourcen als Dateienanhang 
beifügen.

von Lern Instructor (Gast)


Lesenswert?

Korr.:
architecture struct of top is

signal sig_cnt_16b  : std_logic_vector(15 downto 0);
signal sig_cnt_s16b : signed(15 downto 0);

--...
begin
 I_CNT_1 : counter port map (
  CLK => clk,
  Y1  => sig_cnt_16b);

  I_RECT_1 : rectifier port map (
   A  => signed(sig_cnt_16b),
   Y2 => sig_cnt_s16b);

   cntout <= std_logic_vector(sig_cnt_s16b);

end struct;
[/vhdl]

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


Lesenswert?

Wie gesagt: probiers mal so...
rect1  : rect port map...

Und: warum gibst du als Absolutwert ein signed zurück?
Wenn du z.B. einen 8 Bit signed Wert hast, dann geht der von -128 bis 
+127. Wenn jetzt also ein Wert von -128 in deinen Gleichrichter 
hineingeht, was kommt dann bei einem 8 Bit signed Ergebnis wieder 
heraus?

Mark W. schrieb:
> use ieee.std_logic_unsigned.all;
> use ieee.numeric_std.all;
Die numeric_std hat alles, was du brauchst. Mit der alten Synopsys 
std_logic_unsigned bringst du doppelte Definitionen ins Spiel, die zu 
eigenartigem Verhalten des Synthesizers führen können...

: Bearbeitet durch Moderator
von FPGA zum Spass (Gast)


Lesenswert?

Lothar M. schrieb:
> Wenn du z.B. einen 8 Bit signed Wert hast, dann geht der von -128 bis
> +127. Wenn jetzt also ein Wert von -128 in deinen Gleichrichter
> hineingeht, was kommt dann bei einem 8 Bit signed Ergebnis wieder
> heraus?

Interessante Frage: ist der Wert dann 0 oder doch wieder -128?

Habe so eine Stelle auch in einem Stück Code von mir, da ist mir das 
auch nicht aufgefallen.

Eine Warnung gibt es dafür leider nicht, wie ich gerade feststellen 
musste, weder von Modelsim, noch von Quartus.

von Lern Instructor (Gast)


Lesenswert?

FPGA zum Spass schrieb im Beitrag #5876142:

> Interessante Frage: ist der Wert dann 0 oder doch wieder -128?

Tipp: Zweierkomplement

https://de.wikipedia.org/wiki/Zweierkomplement

von Mark W. (kram) Benutzerseite


Angehängte Dateien:

Lesenswert?

Schonmal vielen Dank fuer all die Tips.
Die Code Guidelines sind sehr nuetzlich fuer mich, da ich noch (aus 
vielen verschiedenen Quellen) lerne und jeder macht es halt ein Bisschen 
anders.

Ich hatte den Code eingefuegt, da es nicht soooo lang war. Hier ist mein 
Ergebnis (bis jetzt) im Anhang. Ich muss es noch Pruefen, aber es geht 
schonmal ohne Fehlermeldungen durch.

Ja, die Sache mit dem maximalsten negativen Wert hatte ich auch nicht 
auf dem Schirm, das muss noch abgefangen werden. Es ist ja so, dass nach 
der Gleichrichtung ein bit weniger bei der Aufloesung benoetigt wird. 
Dieses frei gewordene bit koennte man ja hernehmen um dann das Ganze 
wieder hoch skalieren. Mal sehen wie ich das machen werde.

von Markus F. (mfro)


Lesenswert?

FPGA zum Spass schrieb im Beitrag #5876142:
> Eine Warnung gibt es dafür leider nicht, wie ich gerade feststellen
> musste, weder von Modelsim, noch von Quartus.

Da gibt's ja auch nix zu warnen, abs(-128) (auf einem 8Bit-Signed-Wert) 
ist nun mal in der numeric_std implizit als -128 definiert.

Wie kommt man da elegant drum herum? Lustigerweise, indem man gar keine 
numeric_std benutzt:
1
....
2
    subtype s_type is integer range -128 to 127;
3
    subtype u_type is integer range 0 to 255;
4
    signal s    : s_type := -128;
5
    signal u    : u_type := abs(s);
6
begin
7
    assert false report "u=" & u_type'image(u) severity note;
8
...

von FPGA zum Spass (Gast)


Lesenswert?

Mark W. schrieb:
> Es ist ja so, dass nach
> der Gleichrichtung ein bit weniger bei der Aufloesung benoetigt wird.

Eben nicht, sonst wäre es ja kein Problem, weil das "Vorzeichenbit" 0 
bleiben würde.
Bsp -128 -> ergibt nach Absolutwert 128 und dafür brauchst du 8 Bit, 
genauso wie vorher.


Markus F. schrieb:
> Da gibt's ja auch nix zu warnen, abs(-128) (auf einem 8Bit-Signed-Wert)
> ist nun mal in der numeric_std implizit als -128 definiert.

D.h. der Absolutwert auf der vollen Range ist per Definition kaputt, 
weil für diesen einen Fall eben nicht der Absolutwert zurückgeliefert 
wird.

Lieber wäre mir hier, wenn abs(signed) immer einen unsigned zurückgeben 
würde. Wenn ich das nicht will, dann muss ich selbst casten, aber dann 
würde man wenigstens drüber nachdenken.



Beispiel C#:

Int32 a = -2147483648;
Int32 b = Math.Abs(a);

"System.OverflowException: "Das Negieren des minimalen Wertes einer 
Ergänzungszahl ist unzulässig."


C++ warnt leider auch nicht. Da gibts nur eine Warnung wenn man direkt 
den maximalen, negativen Wert zuweisen will.

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.