Forum: FPGA, VHDL & Co. dezimal und kommazahl dividieren


von Jois (Gast)


Lesenswert?

Hallo Leute,

ich möchte zwei std_logic_vector (26 downto 0) und (18 downto0 ) 
dividieren
zB. 2000408(27 bits) durch 277894(19 bits) = 7,198
konnte mir jemand bitte sagen, wie kann ich das Ergebnis in kommazalh 
kriegen?

Grüß,
Jois

von Falk B. (falk)


Lesenswert?

Mit Festkommmaarithmetik. Nichts desto trotz braucht man ein 
Dividierer -IP Core, wenn es ein synthetisierbares Modul werden soll.

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


Lesenswert?

Jois schrieb:
> konnte mir jemand bitte sagen, wie kann ich das Ergebnis in kommazalh
> kriegen?
Ich hätte da noch eine oder zwei Fragen:
Wie genau soll denn diese Kommazahl sein?
Was willst du damit machen?
Wieviele Nachkommastellen brauchst du?
Woher kommen die beiden zu teilenden Zahlen?
Wie schnell muss die Berechnung sein?

von Martin H. (disjunction)


Lesenswert?

Wenn du den Divident um ein paar Nullen erweiterst, kommt das Ergebnis 
in sozusagen als Festkommazahl heraus.

Ich habe mal einen Sequenziellen Dividierer zusammengebaut wenn 
Interesse besteht sag bescheid.

von Tom W. (Gast)


Lesenswert?

Interesse.

von Martin H. (disjunction)


Lesenswert?

1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.STD_LOGIC_ARITH.ALL;
4
use IEEE.STD_LOGIC_UNSIGNED.ALL;
5
6
7
entity Dividierer is
8
 Port ( CLK          : in    std_logic;
9
        RESET        : in    std_logic;
10
        START        : in    std_logic;
11
        READY        : out   std_logic;
12
        Dividend     : in    std_logic_vector;
13
        Divisor      : in    std_logic_vector;
14
        Quotient     : out   std_logic_vector
15
      );
16
end Dividierer;
17
18
architecture Dividierer_Architecture of Dividierer is
19
20
begin
21
22
--assert Quotient'length = (Dividend'length)
23
--    report "Dividierer: Quotient length must equal Dividend length" severity error;
24
25
process (CLK)
26
variable i   : integer range 0 to Dividend'length-1 + 2 := 0;
27
variable q   : std_logic_vector(Dividend'length  downto 0);  -- Ansichtlich etwas länger
28
variable d   : std_logic_vector(Dividend'length-1 downto 0);
29
variable div : std_logic_vector(Dividend'length-1 downto 0);
30
variable x   : std_logic_vector(Dividend'length   downto 0);  -- 1bit läger wegen Subtraktionsüberlauf 
31
variable c   : std_logic;
32
33
constant zeros : std_logic_vector(Dividend'length downto 0) := (others => '0');
34
constant ones  : std_logic_vector(Dividend'length downto 0) := (others => '1');
35
36
begin
37
  if (CLK'event and CLK = '1') then 
38
    if Reset = '0' then 
39
      if i = 0 then 
40
        c   := '0'; 
41
        d   := Dividend; 
42
        div := (others => '0'); 
43
        div := Divisor ; 
44
        q   := (others => '0'); 
45
        x   := (others => '0');
46
        if START = '1' then i := 1; end if;
47
        READY <= '0';
48
      else
49
        c                      := x(x'length-1);
50
        x(x'length-1 downto 0) := x(x'length-2 downto 0) & d(d'length-1);
51
        d(d'length-1 downto 0) := d(d'length-2 downto 0) & '-'; -- don?t care 
52
       
53
        if c = '0' then
54
          x := x - ("0" & div);
55
        else 
56
          x := x + ("0" & div);
57
        end if;
58
        
59
        q(q'length-1 downto 0) := q(q'length-2 downto 0) & not x(x'length-1);      
60
        
61
        i := i + 1;
62
        READY <= '0';
63
        if i = Dividend'length+1 then 
64
         if q(q'length-1 downto Quotient'length) /= zeros(q'length - 1 - Quotient'length downto 0) then
65
            q := (others => '1');
66
          end if;  
67
          
68
          Quotient <= q(Quotient'length-1 downto 0); 
69
          i := 0;
70
          READY <= '1';
71
        end if;
72
      end if;
73
    else
74
        i   := 0;
75
        c   := '0'; 
76
        q   := (others => '0'); 
77
        x   := (others => '0');
78
        READY <= '0';
79
    end if;
80
  end if;
81
end process;
82
83
end Dividierer_Architecture;

von Duke Scarring (Gast)


Lesenswert?

Martin H. schrieb:
> use IEEE.STD_LOGIC_ARITH.ALL;
> use IEEE.STD_LOGIC_UNSIGNED.ALL;
Vielleicht machst Du da nochmal etwas hübscheren Code draus, hier meine 
Kritikpunkte:
1. siehe Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete"
2. exzessive Verwendung von Variablen
3. fehlende Testbench

Duke

von Martin H. (disjunction)


Lesenswert?

Duke Scarring schrieb:
> Martin H. schrieb:
>> use IEEE.STD_LOGIC_ARITH.ALL;
>> use IEEE.STD_LOGIC_UNSIGNED.ALL;
> Vielleicht machst Du da nochmal etwas hübscheren Code draus, hier meine
> Kritikpunkte:
> 1. siehe Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete"
gebongt...
> 2. exzessive Verwendung von Variablen
hat die Logik schön klein gemacht
> 3. fehlende Testbench
mpf...vergessen...ist schon 10 Jahre alt der Code und ich habe die TP 
nie wieder gebraucht...
>
> Duke

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


Lesenswert?

>> 2. exzessive Verwendung von Variablen
> hat die Logik schön klein gemacht
Häh? Wie erklärst du dir das?

Ich hätte da auch was zum Thema:
 http://www.lothar-miller.de/s9y/archives/29-Division-in-VHDL.html

von Martin H. (disjunction)


Lesenswert?

Lothar Miller schrieb:
>>> 2. exzessive Verwendung von Variablen
>> hat die Logik schön klein gemacht
> Häh? Wie erklärst du dir das?
Ich hatte einen Servoregler in einen XC2S100 zu pressen
Number of Slices - war mein größtes Problem und da habe ich angesetzt...
Ich kann es heute auch nicht mehr nachvollziehen. Das Original hatte 
noch einen Multiplexer da ich zwei Divisionen brauchte.

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.