Ich will in Verilog einen "Signed" Wert durch 2 (oder eine andere Zweierpotenz) teilen. Wenn ich das mit einem einfachen Rechts-Shift mache, ist die Arithmetik nicht symmetrisch. Beispiel: 11>>1 ergibt 5 , -11>>1 ergibt aber -6. x= 11 = 0000001011 x>>1= 5 = 0000000101 x= -11 = 1111110101 x>>1= -6 = 1111111010 Ich möchte eine Funktion, die symmetrisch arbeitet, bzw. der üblichen Divsion entspricht. Gibt es eine etablierte Lösung in Verlog?
Martin O. schrieb: > Beispiel: > 11>>1 ergibt 5 Das ist mathematisch falsch. Denn eigentlich wird bei einer Zahl, die genau auf ",5000000..." endet, zur nächsten geraden Zahl hin gerundet. Siehe http://de.wikipedia.org/wiki/Rundung unter "Mathematisches Runden" > -11>>1 ergibt aber -6. Was eigentlich korrekt ist... Wenn du aber unbedingt zwangsweise in Richtung Null runden willst, dann addiere einfach bei einer negativen Zahl eins drauf und schiebe sie dann nach rechts...
Lothar Miller schrieb: >> 11>>1 ergibt 5 > Das ist mathematisch falsch. Bei Schiebeoperation im Zweierkomplement ist das korrekt. > Siehe http://de.wikipedia.org/wiki/Rundung unter "Mathematisches Runden" Schon mal eine Schiebeoperation mit Rundung gesehen?
A. K. schrieb: > Schon mal eine Schiebeoperation mit Rundung gesehen? Nein, aber die Frage war ja nach der Rundung einer negativen Zahl zur Null hin... Der Synthesizer selber wird jede Division, die einfach mit "/2" dasteht durch eine "Schiebeoperation" ersetzen (in der Realität durch einfaches Ignorieren des LSB).
Lothar Miller schrieb: > Der Synthesizer selber wird jede Division, die einfach mit "/2" dasteht > durch eine "Schiebeoperation" ersetzen (in der Realität durch einfaches > Ignorieren des LSB). Gibts in Verilog überhaupt negative Zahlen im Zweierkomplement, oder ist das Sache des Anwenders und das Ergebnis folgt der alten Regel "Schrott rein Schrott raus"? Aber die Lösung ist einfach: Für Zahlen mit Vorzeichen das Einerkomplement an Stelle des Zweierkomplements verwenden. ;-)
:
Bearbeitet durch User
Bei signed shift nimmt man
1 | >>> |
und nicht
1 | >> |
:
Bearbeitet durch Moderator
Frank Fahrenheit schrieb: > Bei signed shift nimmt man
1 | >>> |
Und was wird dann tatsächlich daraus gemacht? In VHDL ist es jedenfalls so, dass bei einem negativen "integer" oder "signed" die Division und auch der Shift nicht symmetrisch ist: es wird einfach das LSB weggelassen.
:
Bearbeitet durch Moderator
Lothar Miller schrieb: > Der Synthesizer selber wird jede Division, die einfach mit "/2" dasteht > durch eine "Schiebeoperation" ersetzen (in der Realität durch einfaches > Ignorieren des LSB). "The integer division shall truncate any fractional part toward 0" (IEEE 1800-2012) Daraus folgt, dass ein Synthesewerkzeug, sofern es den Operator unterstützt, ihn auch entsprechend implementieren muss. Erst schieben wollen, um vermeintlich "unnütze" Logik zu vermeiden und dann meckern, dass es nicht so funktioniert wie man es sich vorstellt. Wer Division meint, soll auch Division sagen und den Rest dem Tool überlassen.
Marcus Harnisch schrieb: > Daraus folgt, dass ein Synthesewerkzeug, sofern es den Operator > unterstützt, ihn auch entsprechend implementieren muss. Ich nehme alles zurück und behaupte das Gegenteil! Natürlich macht der Synthesizer die Signed Division so, dass er erst das Zweierkomplement bildet, dann abschneidet und dann wieder das Zweierkomplement bildet. Dementsprechend braucht er für die signed-Division 2 Addierer: Macro Statistics # Adders/Subtractors : 2 8-bit adder : 2
1 | library IEEE; |
2 | use IEEE.STD_LOGIC_1164.ALL; |
3 | use IEEE.NUMERIC_STD.ALL; |
4 | |
5 | entity DivVsShift is |
6 | port ( slv : in std_logic_vector (7 downto 0); |
7 | |
8 | uns_shift : out std_logic_vector (7 downto 0); |
9 | uns_div : out std_logic_vector (7 downto 0); |
10 | sig_shift : out std_logic_vector (7 downto 0); |
11 | sig_div : out std_logic_vector (7 downto 0) |
12 | );
|
13 | end DivVsShift; |
14 | |
15 | architecture Behavioral of DivVsShift is |
16 | begin
|
17 | uns_div <= std_logic_vector( unsigned(slv) / 8); |
18 | uns_shift <= std_logic_vector( shift_right( unsigned(slv), 3)); |
19 | sig_div <= std_logic_vector( signed(slv) / 8); |
20 | sig_shift <= std_logic_vector( shift_right( signed(slv), 3)); |
21 | end Behavioral; |
Für Datentypen mit Vorzeichen: >>> oder <<< Wird in Verilog einfacher geregelt, nicht so kompliziert wie in VHDL. http://www.asic-world.com/verilog/verilog2k1.html (bis zur Mitte scollen) --------------------------- Und was wird dann tatsächlich daraus gemacht? --------------------------- Natürlich bleibt es eine Signed..... Natürlich muss sie vorher so deklariert werden : reg signed [7:0] a; so ist es immer eine unsigned: reg signed [7:0] a; Gruss
:
Bearbeitet durch User
Peter Bierbach schrieb: > Wird in Verilog einfacher geregelt, nicht so kompliziert wie in VHDL. Was ist an einen /2 kompliziert? Natürlich muss man auch dort den richtigen Datentypen verwenden. Der erwähnte Dreizack als arithmetischer Shift ist zwar tricky, aber nicht unbedingt intuitiv...
:
Bearbeitet durch Moderator
----------------------------------- Der erwähnte Dreizack als arithmetischer Shift ist zwar tricky, aber nicht unbedingt intuitiv... ----------------------------------- Es geht auch ohne Textromane.... um etwas auszuführen. Damals hat man in "C" so gedacht als es erfunden wurde. Und einige Befehle von "C" sind danach in vielen anderen Sprachen übernommen worden...,... Gruss
Peter Bierbach schrieb: > Natürlich muss sie vorher so deklariert werden : > reg signed [7:0] a; > > so ist es immer eine unsigned: > reg signed [7:0] a; Super Erklaerung! Peter, ich danke dir! Du hast mich technisch und menschlich richtig weit nach vorn' gebracht... Au Mann...
Peter Bierbach schrieb: > ----------------------------------- > Der erwähnte Dreizack als arithmetischer Shift ist zwar tricky, aber > nicht unbedingt intuitiv... > ----------------------------------- > Es geht auch ohne Textromane.... um etwas auszuführen. Und was genau ist an "/2" wesentlich länger oder gar unverständlicher als an ">>>"?
Lothar Miller schrieb: > Und was genau ist an "/2" wesentlich länger oder gar /unverständlicher/ > als an ">>>"? Der Unterschied ist, dass /2 für den gegebenen Fall das richtige Ergebnis erzeugt ;)
Martin O. schrieb: > Beispiel: > 11>>1 ergibt 5 , > -11>>1 ergibt aber -6. Dieses Abrunden ist Programmierern auch unter dem Namen FLOOR bekannt: http://de.wikipedia.org/wiki/Abrundungsfunktion_und_Aufrundungsfunktion
------------------------ berndl (Gast) ----------------------- So ist es nun, einige Veriloger nehmen an , das sie einfach : reg [7:] test=-23 ; setzen können. Natürlich geht das , es wird eine -23 draus wenn ich die Bits arithmetisch betrachte. Wird aber bei jeder Benutzung als unsigned genommen.
--------------------------------------- Der Unterschied ist, dass /2 für den gegebenen Fall das richtige Ergebnis erzeugt ;) --------------------------------------- Hier wird mehr Platz verschwendet im FPGA , beim VERILOG weniger. Nur probieren....dann sieht man das Ergebnis. Gruss
peter schrieb: > Hier wird mehr Platz verschwendet im FPGA , beim VERILOG weniger. Vermutlich, weil etwas Anderes gemacht wird. Einfach ausprobieren... Eine Signed-Division brauch nun mal das Zweierkomplement weil sie etwas Anderes ist als ein Rechtsshift...
Besten Dank für die (größtenteils) hilfreichen Anregungen. Problemlösung bei mir war die Verwendung von /4096 zusammend mit der konsequenzen Verwendung von "signed". Im nachhinein naheliegend, aber für mich als Verilog/FPGA Anfänger gibt's halt doch viel zu lernen.
-------------------------------------- Vermutlich, weil etwas Anderes gemacht wird. -------------------------------------- Wahrscheinlich wird da ein anderer Weg genommen, vermute ich auch. Gruss
peter schrieb: > Wahrscheinlich wird da ein anderer Weg genommen, vermute ich auch. Kommt denn bei der vereinfachten Verilog Beschreibung auch das richtige Ergebnis raus?
------------------------------ Kommt denn bei der vereinfachten Verilog Beschreibung auch das richtige Ergebnis raus? ------------------------------- Wenn ich den weg : reg signed [7:0] a; einhalte ja. bei : reg [7:0] a; werden alle Bits normal berechnet ala "unsigned" Gruss
Hmmm... Bei >>> oder <<< wird das 7.Bit nicht mit genommen. Bie >> oder << wird es mit genommen: Gruss
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.