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:
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
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]
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...
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.
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.
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:
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.