Forum: FPGA, VHDL & Co. Binär Dividierer: Restoring Methode


von Lin (Gast)


Lesenswert?

Hallo,

ich versuche momentan den Restoring Algorithmus beim binären Dividieren 
zu verstehen. Ich habe folgenden Quellcode im Internet gefunden und habe 
die Simulation gestartet.
Den Clock habe ich eingestellt und Werte für x und y. Leider verstehe 
ich nicht ganz, wo das Ergebnis "gespeichert wird".

Kann mir das jemand vielleicht sagen bzw. erklären?
1
----------------------------------------------------------------------------
2
-- restoring.vhd
3
--
4
-- Implements a sequential version of restoring division algorithm
5
-- section 3.2 Loop-unrolling and digit-serial processing
6
-- x = xn-1 xn-2 ... x0: natural
7
-- y = yn-1 yn-2 ... y0: natural
8
-- condition: x < y
9
-- quotient q =  0.q1 ... qp: non-negative fractional
10
-- remainder r = rn-1 rn-2 ... r0: natural
11
-- x = (0.q1 q2 ... qp)·y + (r/y)·2-p with r < y
12
--
13
----------------------------------------------------------------------------
14
15
LIBRARY IEEE;
16
USE IEEE.STD_LOGIC_1164.ALL;
17
USE IEEE.STD_LOGIC_ARITH.ALL;
18
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
19
ENTITY restoring IS
20
  GENERIC(n: NATURAL:=8; p: NATURAL:= 6);
21
PORT(
22
  x, y: IN STD_LOGIC_VECTOR(n-1 DOWNTO 0);
23
  clk, reset, start:IN STD_LOGIC;
24
  quotient: OUT STD_LOGIC_VECTOR(1 TO p);
25
  remainder: OUT STD_LOGIC_VECTOR(n-1 DOWNTO 0);
26
  done: OUT STD_LOGIC
27
);
28
END restoring;
29
30
ARCHITECTURE circuit OF restoring IS
31
  SIGNAL r, next_r: STD_LOGIC_VECTOR(n-1 DOWNTO 0);
32
  SIGNAL long_y, two_r, dif: STD_LOGIC_VECTOR(n DOWNTO 0);
33
  SIGNAL load, update: STD_LOGIC;
34
  SIGNAL q: STD_LOGIC_VECTOR(1 TO p);
35
  
36
  SUBTYPE index IS NATURAL RANGE 0 TO p-1;
37
  SIGNAL count: index;
38
  TYPE state IS RANGE 0 TO 3;
39
  SIGNAL current_state: state;
40
  
41
BEGIN
42
  long_y <= '0'&y;
43
  two_r <= r&'0';
44
  dif <= two_r - long_y;
45
  WITH dif(n) SELECT next_r <= dif(n-1 DOWNTO 0) WHEN '0', two_r(n-1 DOWNTO 0) WHEN OTHERS;
46
47
  remainder_register: PROCESS(clk)
48
  BEGIN
49
    IF clk'EVENT AND clk = '1' THEN
50
      IF load = '1' THEN r <= x;
51
      ELSIF update = '1' THEN r <= next_r;
52
      END IF;  
53
    END IF;
54
  END PROCESS;
55
  remainder <= r;
56
57
  quotient_register: PROCESS(clk)
58
  BEGIN
59
    IF clk'EVENT AND clk = '1' THEN
60
      IF load = '1' THEN q <= (others => '0');
61
      ELSIF update = '1' THEN q <= q(2 TO p)&NOT(dif(n));
62
      END IF;  
63
    END IF;
64
  END PROCESS;
65
  quotient <= q;
66
67
  counter: PROCESS(clk)
68
  BEGIN
69
    IF clk'EVENT and clk = '1' THEN
70
      IF load = '1' THEN count <= 0; 
71
      ELSIF update = '1' THEN count <= (count+1) MOD p;
72
      END IF;
73
    END IF;
74
  END PROCESS;
75
76
  next_state: PROCESS(clk)
77
  BEGIN
78
    IF reset = '1' THEN current_state <= 0;
79
    ELSIF clk'EVENT AND clk = '1' THEN
80
      CASE current_state IS
81
        WHEN 0 => IF start = '0' THEN current_state <= 1; END IF;
82
        WHEN 1 => IF start = '1' THEN current_state <= 2; END IF;
83
        WHEN 2 => current_state <= 3;
84
        WHEN 3 => IF count = p-1 THEN current_state <= 0; END IF;
85
      END CASE;
86
    END IF;
87
  END PROCESS;
88
89
  output_function: PROCESS(clk, current_state)
90
  BEGIN
91
    CASE current_state IS
92
      WHEN 0 TO 1 => load <= '0'; update <= '0'; done <= '1';
93
      WHEN 2 => load <= '1'; update <= '0'; done <= '0';
94
      WHEN 3 => load <= '0'; update <= '1'; done <= '0';
95
    END CASE;
96
  END PROCESS;
97
  
98
END circuit;

Quelle: http://www.arithmetic-circuits.org/guide2fpga/vhdl_codes.htm

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


Lesenswert?

Lin schrieb:
> Leider verstehe ich nicht ganz, wo das Ergebnis "gespeichert wird".
Sieh dir die Ports des Moduls an: das Ergebnis wird im quotient und 
remainder zurück gegeben.
Wobei die Bitreihenfolge des quotient etwas unerwartet ist...

von Lin (Gast)


Lesenswert?

Hallo,

danke für deine Antwort. Leider bekomme ich in Modelsim kein Ergebnis. 
Ich habe die Clock gesetzt, x und y festgelegt, aber ich bekomme in der 
Simulation kein Ergebnis. 'quotient' wird nicht beschrieben.
Woran kann das liegen? Welche Werte muss ich noch angeben in Modelsim?

von Duke Scarring (Gast)


Angehängte Dateien:

Lesenswert?

In meinem Modelsim tut sich was.
Möglicherweise hast Du das 'start'-Signal nicht betätigt oder die 
Reset-Polarität ist falsch.

Duke

von Lin (Gast)


Lesenswert?

Danke für deine Antwort. Ich bin gerade auf der Arbeit, werde heute 
Abend nochmal meine Simulation überprüfen. Ich hatte eigentlich das 
start-Signal gesetzt. Eigentlich sollte es dann auch bei mir 
funktionieren.

von VHDL Polizei (Gast)


Lesenswert?

Wieso verwendest Du IF und CASE?  Also Parallele Strukturen und dann 
dennoch Vorrang mit IF?  Was ist mit den ELSE Wegen? Ist das alles 
vollständig beschrieben?

von -gb- (Gast)


Lesenswert?

Das solltest Du besser den Verfasser des Codes fragen.

von Lin (Gast)


Lesenswert?

Hallo,

ich habe den Code nicht selber geschrieben. Ich versuche die restoring 
division Methode zu verstehen, deshalb hat sich das angeboten, ein schon 
gegebenes VHDL zu simulieren.

@Duke Scarring, ich hatte einen Fehler in meiner Testbench. Jetzt läuft 
es und ich habe deine Testbench auch probiert, leider kriege keine ich 
richtigen Ergebnisse.

Die VHDL Beschreibung sollte richtig sein, also kann es nur an der TB 
liegen.

Woran könnte es liegen, dass ich falsche Rechenergebnisse bekomme? Hat 
irgendjemand eine Idee?

von Duke Scarring (Gast)


Lesenswert?

Lin schrieb:
> Woran könnte es liegen, dass ich falsche Rechenergebnisse bekomme?
Es könnte an der komischen Bitordnung des Quotienten liegen.
Oder an
1
-- condition: x < y
oder an
1
-- quotient q =  0.q1 ... qp: non-negative fractional

Im Zweifel würde ich mir die Division selbst schreiben.
Der vorgegebene Code ist mehr als merkwürdig:
- arith statt numeric_std
- uraltes clk'event statt rising_edge
- States der FSM nummeriert statt benamst
- 3 getaktete Prozess statt einem
- unübersichtliche nebenläufige Logik (with und output_function)

Was für Werte willst Du denn dividieren?
Und wie schnell muß das laufen?

Duke

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.