Forum: FPGA, VHDL & Co. Division


von Anfänger (Gast)


Lesenswert?

Ich habe einen Wert, der sich unregelmäßig ändert.
Immer wenn dieser Wert sich ändert brauche ich auch (Wert/360).
Mir fehlt im Augenblick eine vernünftige Idee.

Ich bin für jeden Ratschlag dankbar.

von SiO2 (Gast)


Lesenswert?

Ich glaube, du solltest deine Frage besser Formulieren.
Naja, vielleicht denke ich richtig:
1
Wert lesem
2
Wert speichern
3
wert lesen
4
wert mit gespeichertem vergleichen
5
ungleich?
6
ja==> wert/360
mit dem wert machen was du willst
7
goto 3

so ungefaehr

von Neutron (Gast)


Lesenswert?

Wie wird in VHDL denn eine Division realisiert? Muss man dafür nicht
gleich eine ALU implementieren?

von Johannes Fottner (Gast)


Lesenswert?

Wenn die Division immer den gleichen Divisor hat dann ist es einfach:

y = x* 1/Divisor.
1/Divisor kannst du vorab ausrechnen und die Multiplikation ist
einfach.

von Henning (Gast)


Lesenswert?

hallo zusammen,

ich will mich mit meiner frage zur division mal hier einreihen um nicht
extra ein thread aufzumachen.

also bei mir ist das problem, das ich einen wert im nenner stehen habe,
welcher sich ändert (z.b. 100000/wert).

deswegen habe ich folgenden code mir überlegt (hier ist wert noch als
konstant angenommen um ein kostantes ergebnis zu bekommen)

entity division is
    Port ( wert : out integer;
        clk1: in std_logic);  -- clk1 etwa 1MHz, abgeleitet  -
                      --von den 50MHz des spartan3-boards
end division;

architecture Behavioral of division is
signal zahl : integer := 6324;
signal divcount :integer:= 0;
signal divcount2 :integer:= 0;
signal hilf: integer := 0;
begin
process (clk1, hilf, divcount)
begin

    if clk1 = '1' and clk1'event then
      wert <= divcount2;
      hilf <= 0;
      divcount <= 0;

    end if;

    if (hilf + zahl) <= 1000000 then
      hilf <= hilf +zahl;
      divcount <=  divcount +1;
    else
      divcount2 <= divcount;
    end if;
end process;
end Behavioral;

mein problem ist aber nun, dass das ergebnis sehr nervös hin und her
zappelt und nicht den eindruck macht, dass dieses gezappel irgendetwas
mit dem ergebnis meiner division zutun hat.
gebe ich einen festen wert als ausgabe zurück, dann zappelt meine
anzeige auch nicht, somit sollte alles weiter korrekt sein.

ich hoffe es ist nur ein dummer anfänger fehler...
ich nehme auch gerne alternative divisions-codes entgegen, bei denen es
zu konstanten ergebnissen kommt.

besten dank euch allen
henning

von high_speed (Gast)


Lesenswert?

Hallo Henning

Dein Code wird so nicht funktionieren.
Durch Laufzeiteffekte wird deine Rechenschaltung nie zu einem stabilen
Ergebnis kommen.
So etwas kann höchstens in einer getakten Umgebung funktionieren.
Wie viele Takte willst du auf das Ergebnis warten?
Ansonsten musst du mal schauen, ob in deinem FPGA entsprechende
Divisionszellen integriert sind.

MfG
Holger

von Henning (Gast)


Lesenswert?

gut... da sieht also jemand schon mein problem :-)
dann suchen wir nun mal eine gemeinsamme lösung !?

angenommen, ich würde den original takt des spartan3-boards nehmen,
also die 50MHz, dann hätte ich ja theoretisch 50.000 takte zeit bis
mein 1kHz takt wieder kommt.

da noch nicht klar ist welches fpga später eingesetzt wird, würde ich
gerne auf spezielle interne bausteine verzichten.

gruß henning

von Ines (Gast)


Lesenswert?

Hallo Henning,

ich habe Deinen Code mal überarbeitet. Ich übernehme aber keine Gewähr
auf Kompilierbarkeit oder gar Synthesefähigkeit. Und für die Funktion
bist Du selbst verantwortlich.

OK, nachdem ich mich jetzt rechtlich abgesichert habe :-), sollte ich
vielleicht noch erwähnen, dass ich aber durchaus für Rückfragen etc.
zur Verfügung stehe. Schau's Dir halt mal an - hoffentlich hilft es
Dir weiter!

Gruß
Ines


entity division is
  Port
  (
    Clk   : in  std_logic;
    Reset : in  std_logic;
    Clk1  : in  std_logic; -- clk1 etwa 1MHz
    Wert  : out integer
  );
end division;

architecture Behavioral of division is
  signal zahl      : integer;
  signal divcount  : integer;
  signal divcount2 : integer;
  signal hilf      : integer;
  signal clk1_last : integer;
begin
  process (Clk, Reset)
  begin

    if Reset = '0' then  -- low aktive reset
      Wert      <= 0;
      zahl      <= 6324;
      divcount  <= 0;
      divcount2 <= 0;
      hilf      <= 0;
      clk1_last <= '0';
    elsif Clk = '1' and Clk'event then        -- Systemtakt

      clk1_last <= Clk1;

      if Clk1 = '1' and clk1_last = '0' then  -- Divisionstakt
        Wert     <= divcount2;
        hilf     <= 0;
        divcount <= 0;
      end if;

      if (hilf + zahl) <= 1000000 then
        hilf     <= hilf + zahl;
        divcount <= divcount + 1;
      else
        divcount2 <= divcount;
      end if;
    end if;

  end process;
end Behavioral;

von Udo (Gast)


Lesenswert?

Seht Euch doch mal den Unsigned Divider auf Opencores an

http://www.opencores.org/projects.cgi/web/serial_div_uu/overview

Ist zwar Verilog aber die Experten (ich leider nicht) von Euch sollten
da schon durchsteigen. Könnte zumindest ein Anhaltspunkt für eine
eigene Lösung sein.

Der wird sicherlich auch etwas schneller sein :
Taktzyklen = Anzahl Bits des Quotienten + 1

Ich bin mal gespannt, weil das Thema mich auch interessiert.

von Henning (Gast)


Lesenswert?

supi...

die lösung von ines funktioniert bis auf einen kleinen syntax-fehler
ganz gut. ich hoffe, dass dieser gute eindruck auch beim einbinden in
das komplette projekt weiter funktioniert.

wäre es nun noch möglich mir in wenigen worten zu erklären warum meine
variante aufgrund von laufzeiten nicht funktionieren konnte?

liebe grüsse aus bremen
henning

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.