Binär Dividierer: Restoring Methode

Gast #5040827
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
Gast #5041220
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?
Gast #5041502
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.
Gast #5045469
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?
Gast #5046740
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

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