Forum: FPGA, VHDL & Co. Verilog: Signed Division durch Zweierpotenz


von Martin O. (ossi-2)


Lesenswert?

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?

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


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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?

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


Lesenswert?

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).

von (prx) A. K. (prx)


Lesenswert?

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
von Frank F. (frank_f49)


Lesenswert?

Bei signed shift nimmt  man
1
>>>
und nicht
1
>>

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


Lesenswert?

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
von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

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.

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


Lesenswert?

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;

von Peter B. (funkheld)


Lesenswert?

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
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
von Peter B. (funkheld)


Lesenswert?

-----------------------------------
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

von berndl (Gast)


Lesenswert?

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

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


Lesenswert?

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 ">>>"?

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

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

von foo (Gast)


Lesenswert?

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

von peter (Gast)


Lesenswert?

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

von peter (Gast)


Lesenswert?

---------------------------------------
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

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


Lesenswert?

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

von Martin O. (ossi-2)


Lesenswert?

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.

von peter (Gast)


Lesenswert?

--------------------------------------
Vermutlich, weil etwas Anderes gemacht wird.
--------------------------------------

Wahrscheinlich wird da ein anderer Weg genommen, vermute ich auch.

Gruss

von Christian R. (supachris)


Lesenswert?

peter schrieb:
> Wahrscheinlich wird da ein anderer Weg genommen, vermute ich auch.

Kommt denn bei der vereinfachten Verilog Beschreibung auch das richtige 
Ergebnis raus?

von peter (Gast)


Lesenswert?

------------------------------
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

von peter (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.