elegant durch 4 teilen mit aufrunden

Gast #4526422
Hallo Leute,

ich würde gerne wissen wie ich ein Signal durch 4 teilen kann und das 
Ergebniss aufgerundet bekomme. Bei Zahlen die durch 4 ohne Rest teilbar 
sind, ist das easy. Ich lasse einfach die ersten 2 Bits weg
Beispiel:

20 : 4 = 5

signal zahl : unsigned(4 downto 0 ) := "10100";
signal erg : unsigned(4 downto 0 );

erg <= zahl(4 downto 2); --101

So wie sieht das jetzt aber mit Zahlen aus die nicht restlos durch 4 
teilbar sind, aus? Ich brauche das Ergebnis Aufgerundet

Beispiel:

19 : 4 = 4,75 -> 5

Wenn ich hier die ersten beiden bits von rechts weglasse dann erhalte 
ich 4 als Ergebnis. Ich benötige aber immer die nächsthöhere Zahl wenn 
das Ergebnis einen Rest hat.

Ist das irgendwie elegant zu lösen ohne große Bibliotheken oder 
Divisionsalgorithmen?
Danke schon mal im vorraus

mfg

Flopga
Gast
Eine Frage hätte ich noch. Wenn ich jetzt (X+3)/4 realisieren möchte, 
wie mache ich das am besten?
Das wäre jetzt mein Weg:

test: process (clk)
begin

  if rising_edge(clk) then
      temp <= zahl + 3;
            erg <= temp(Obergrenze downto 2);
  end if;

end process;

Damit wäre mein Ergebnis um einen clock-zyklus zeitversetzt. Ich denke 
mal das wird so funktionieren. Wie wäre das aber wenn ich das mit 
Variablen realisieren wollte? Dann würde es ja sofort funktionieren ohne 
die Zeitverzögerung nehme ich an. Wie sieht es dann mit dem 
Hardwareaufwand aus? Kann man das so sagen das man mit Variablen immer 
mehr Hardwareaufwand hat? Ich möchte nämlich sehr platzsparend meine 
Logik aufbauen.
Ich weiss nicht genau wie das Synthesetool variablen realisiert...
Danke
Gast
Da D. schrieb:
> Flopga schrieb:
>> Wenn ich jetzt (X+3)/4 realisieren möchte,
>
> Dann schreibst du einfach erg <= zahl + 3 / 4;
>
> Mach dir das Leben doch nicht selber schwerer als nötig ;-)

Dieser Weg ist aber nur mit Variablen möglich oder? Eine Division möchte 
ich ja gerade umgehen weil das immer viel Hardwareaufwand bedeutet. 
Deshalb ja der Schieberegister.
Moderator (Firma: Titel) Persönliche Seite
Flopga schrieb:
> Dieser Weg ist aber nur mit Variablen möglich oder?
Nein, warum sollten Variablen Vorteile gegenüber Signalen haben?
Kleiner Tipp: als Anfänger brauchst du keine Variable. Und wenn du doch 
eine brauchst, dann musst du einen guten Grund dafür liefern...

> Eine Division möchte ich ja gerade umgehen weil das immer viel
> Hardwareaufwand bedeutet. Deshalb ja der Schieberegister.
Eine Division einer vorzeichenlosen Zahl durch eine Zweierpotenz ist ein 
simples Umverdrahten im FPGA, also das und Ignorieren von 
niederwertigen Bits. Dazu ist nicht mal ein Schieberegister nötig. Aber 
vermutlich meinst du mit "Schieberegister" sowieso nur den 
"Schiebeoperator"...
Gast
Lothar M. schrieb:
> Flopga schrieb:
>> Dieser Weg ist aber nur mit Variablen möglich oder?
> Nein, warum sollten Variablen Vorteile gegenüber Signalen haben?
> Kleiner Tipp: als Anfänger brauchst du keine Variable. Und wenn du doch
> eine brauchst, dann musst du einen guten Grund dafür liefern...
>
>> Eine Division möchte ich ja gerade umgehen weil das immer viel
>> Hardwareaufwand bedeutet. Deshalb ja der Schieberegister.
> Eine Division einer vorzeichenlosen Zahl durch eine Zweierpotenz ist ein
> simples Umverdrahten im FPGA, also das und Ignorieren von
> niederwertigen Bits. Dazu ist nicht mal ein Schieberegister nötig. Aber
> vermutlich meinst du mit "Schieberegister" sowieso nur den
> "Schiebeoperator"...

Ok danke dann hab ich da etwas missverstanden. Das heisst ich definiere 
mir unsigned signale und kann dann den Operator / einfach benutzen? Und 
das funktioniert auch in der Synthese? Dachte man muss einen speziellen 
Algorithmus verwenden um eine Division zu durchzuführen in VHDL.
Moderator (Firma: Titel) Persönliche Seite
Flopga schrieb:
> Das heisst ich definiere mir unsigned signale und kann dann den Operator
> / einfach benutzen?
Nein, du verknotest da komplett unabhängige Dinge:
1. Nimm Signale statt Variablen.
2. Nimm im Ausnahmefall mit guter Begründung auch mal eine Variable.
3. Vorzeichenlose Divisionen durch eine Zweierpotenz(1,2,4,8,16,32...) 
werden von Synthesizer durch umverdrahten und Abschneiden der unteren 
Bits ersetzt.


Zu den Punkten 1 und 2 siehe den 
Beitrag "Variable vs Signal"
Ein Tipp: ließ den Thread so oft durch, bis du verstanden hast, worum es 
geht...

> Dachte man muss einen speziellen Algorithmus verwenden um eine Division
> zu durchzuführen in VHDL.
Richtig. Das gilt für jegliche Zahl, die keine Zweierpotenz ist: 
3,5,6,7,9,10,11,12,13,14,15,17,18,19...


> Dachte man muss einen speziellen Algorithmus verwenden um eine Division
> zu durchzuführen in VHDL.
Sowas z.B. 
http://www.lothar-miller.de/s9y/archives/29-Division-in-VHDL.html
Allerdings kann man eine Division durch eine Konstante auch durch eine 
Multiplikation (und die anschließende "kostenlose" Division durch eine 
Zweierpotenz) ersetzen.
So wie z.B. im Beitrag "Re: Integer aufspalten" eine 
Division /1000 vorgestellt wird.
Persönliche Seite
Ist hier noch Niemandem aufgefallen, daß hier falsch gerundet wird?

Entweder rundet man statistisch oder deterministisch mit Rauschen - oder 
man wertet alles oberhalb von 0,5 zur 1.0 auf. Dann aber muss zuvor 2 
und nicht mit 3 addiert werden. Nett sind in diesem Zusammenhang 
Divisionen durch 7 bei vorheriger Addition von 3.5 :-)
Jürgen S. schrieb:
> Ist hier noch Niemandem aufgefallen, daß hier falsch gerundet wird?

Es gibt verschiedene Arten zu runden, hier ist das aufrunden gefragt:
Flopga schrieb:
> Ich benötige aber immer die nächsthöhere Zahl wenn
> das Ergebnis einen Rest hat.

Beispiel: Man braucht 17 Stück von irgendwas, was in 4er Packungen 
geliefert wird. Dann braucht man 5 Packungen, auch wenn die 17 der 16 
näher ist als der 20.
Persönliche Seite

Duke Scarring schrieb:

Habt Ihr Schlafprobleme oder nur um die Zeit eure produktiven Phasen?!?

Hobbyastronomen haben nachts was zu tun.

S. R. schrieb:

Das ist aber schön, dass dir das nach 10 Monaten auffällt.

Ich kann noch mehr, wie du siehst und habe einen langen Atem

Falls man es sauber machen will:

1
    function round_sym( a     : signed; shift : positive ) return signed is
2

3
        variable r    : signed(a'range);
4
        variable mag  : signed(a'range);
5
        variable bias : signed(a'range);
6

7
    begin
8
        bias := to_signed( 2**(shift-1), a'length );
9

10
        if a(a'high) = '0' then
11
            r := shift_right( a + bias, shift);
12
        else
13
            mag := -a;
14
            r := -shift_right( mag + bias, shift);
15
        end if;
16
    return r;
17
 end function;
Beitrag #8088357 wurde vom Autor gelöscht.
Beitrag #8088396 wurde vom Autor gelöscht.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.