mikrocontroller.net

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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Mark W. (kram) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity rect is
  port
    (
      A : in signed(15 downto 0);
      Y2 : out signed(15 downto 0)
    );
end rect;

architecture BEHAVIOR of rect is

begin

process (A) is

begin
    Y2 <= abs(A);
end process;

end BEHAVIOR;
Und hier das Toplevelmodul:
library IEEE;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;

entity TOP is
  port(
    CLK    : in std_logic;
    CNTOUT : out std_logic_vector(15 downto 0)
    );
end TOP;

architecture STRUCTURE of TOP is

signal S : std_logic_vector(15 downto 0);

component COUNTER
  port
    (
    CLK : in std_logic;
    Y1 : out std_logic_vector(15 downto 0)
    );
end component;

component rect
port
    (
      A : in signed(15 downto 0);
      Y2 : out signed(15 downto 0)
    );
end component;

begin
COUNTER1 : COUNTER port map (CLK => CLK, Y1 => S);
rect   : rect port map (std_logic_vector(A) => S, std_logic_vector(Y2) => CNTOUT);

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

Autor: VHDL-Polizei (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Instanzennamen ändern!

Autor: Lern Instructor (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

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 => Y2);

   cntout <= std_logic_vector(sig_cnt_s16b);

end struct;


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

Autor: Lern Instructor (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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]

Autor: Lothar M. (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: FPGA zum Spass (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lern Instructor (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Mark W. (kram) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Markus F. (mfro)
Datum:

Bewertung
0 lesenswert
nicht 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:
....
    subtype s_type is integer range -128 to 127;
    subtype u_type is integer range 0 to 255;
    signal s    : s_type := -128;
    signal u    : u_type := abs(s);
begin
    assert false report "u=" & u_type'image(u) severity note;
...

Autor: FPGA zum Spass (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

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.

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