elegant durch 4 teilen mit aufrunden

Gast #4526422
Lesenswert?

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 #4526517
Lesenswert?

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 #4526854
Lesenswert?

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 #4527054
Lesenswert?

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 #4527102
Lesenswert?

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 #4527161
Lesenswert?

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.
#4527749
Lesenswert?

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 #8088349
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren