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;
|