OpenCores
URL https://opencores.org/ocsvn/qfp32/qfp32/trunk

Subversion Repositories qfp32

[/] [qfp32/] [trunk/] [Units/] [recp.vhd] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 mgraep
-- Copyright (c) 2013 Malte Graeper (mgraep@t-online.de) All rights reserved.
2
 
3 2 mgraep
library IEEE;
4
use IEEE.std_logic_1164.all;
5
use IEEE.numeric_std.all;
6
 
7
library work;
8
use work.qfp_p.all;
9
 
10
entity qfp32_recp is
11
 
12
  port (
13
    clk_i     : in  std_ulogic;
14
    reset_n_i : in  std_ulogic;
15
 
16
    start_i : in  std_ulogic;
17
    ready_o : out std_ulogic;
18
 
19
    regA_i : in  qfp32_t;
20
 
21
    complete_o : out std_ulogic;
22
    result_o   : out qfp32_raw_t);
23
 
24
end qfp32_recp;
25
 
26
architecture Rtl of qfp32_recp is
27
 
28
  -- r=(1/d)*2^(29)
29
  -- shifting rem left each time (in loop), the result is effectivly multiplied by 2^(29)
30
  -- QFPx0: d = v*2^24
31
  -- QFPx8: d = v*2^16
32
  -- QFPx16: d = v*2^8
33
  -- QFPx24: d = v*2^0
34
 
35
  -- instead of shift mant left (if needed, at most 5bits) the dividend "1" is shifted right eg. divided by at most 32
36
  -- therefore the remainder reg has to be appended with additional 5bits for storing values less than 1
37
  -- overflow bit is although needed => ov 1bit + mant 29bits + add 5bits
38
 
39
  -- dividend > 1:
40
  --    1*2^x
41
  --    rem( >5 ) <= '1'
42
 
43
  -- dividend = 1:
44
  --    1
45
  --    rem(5) <= '1'
46
 
47
  -- dividend < 1:
48
  --    1*2^-x
49
  --    rem( <5 ) <= '1'
50
 
51
  -- MOD
52
  -- generate rounding bit => iterate 30cycles instead
53
 
54
  signal p1_mant : unsigned(28 downto 0);
55
  signal p1_fmt : qfp_fmt_t;
56
  signal p1_rem : unsigned(34 downto 0);
57
 
58
  signal p2_busy : std_ulogic;
59
  signal p2_mant : unsigned(28 downto 0);
60
  signal p2_fmt : qfp_fmt_t;
61
  signal p2_rem : unsigned(34 downto 0);
62
  signal p2_rem_shft : unsigned(34 downto 0);
63
  signal p2_rem_next : unsigned(34 downto 0);
64
 
65
  signal p2_sub : unsigned(29 downto 0);
66
  signal p2_quo : unsigned(29 downto 0);-- extend by 1 bit for calc rounding bit!!
67
  signal p2_quo_shft : unsigned(29 downto 0);
68
  signal p2_quo_next : unsigned(29 downto 0);
69
  signal p2_cnt : unsigned(4 downto 0);
70
  signal p2_complete : std_ulogic;
71
  signal p2_complete_1d : std_ulogic;
72
 
73
begin  -- Rtl
74
 
75
  process (clk_i, reset_n_i)
76
  begin  -- process
77
    if reset_n_i = '0' then             -- asynchronous reset (active low)
78
      p2_busy <= '0';
79
      p2_rem <= to_unsigned(0,35);
80
      p2_fmt <= (qfp_x0,'0');
81
      p2_mant <= to_unsigned(0,29);
82
      p2_quo <= to_unsigned(0,30);
83
      p2_cnt <= to_unsigned(0,5);
84
      p2_complete_1d <= '0';
85
    elsif clk_i'event and clk_i = '1' then  -- rising clock edge
86
      p2_complete_1d <= '0';
87
      if start_i = '1' and p2_busy = '0' then
88
        p2_rem <= p1_rem;
89
        p2_fmt <= p1_fmt;
90
        p2_mant <= p1_mant;
91
        p2_quo <= to_unsigned(0,30);
92
        p2_cnt <= to_unsigned(29,5);
93
        p2_busy <= '1';
94
      elsif p2_busy = '1' then
95
        p2_rem <= p2_rem_next;
96
        p2_quo <= p2_quo_next;
97
        p2_cnt <= p2_cnt-1;
98
        if p2_complete = '1' then
99
          p2_complete_1d <= '1';
100
          p2_busy <= '0';
101
          -- reset count
102
          p2_cnt <= to_unsigned(29,5);
103
        end if;
104
      end if;
105
    end if;
106
  end process;
107
 
108
  process (p1_mant, p2_mant, p2_quo(28 downto 0), p2_quo_shft,
109
           p2_rem(33 downto 0), p2_rem_shft, p2_rem_shft(34 downto 5), p2_sub,
110
           p2_sub(29), regA_i.fmt.sign, regA_i.mant, rega_i.fmt.exp)
111
  begin  -- process
112
 
113
    -- stage 1
114
    p1_mant <= unsigned(regA_i.mant);
115
 
116
    -- shift dividend and initial reminder correct
117
    -- so that no other correction is needed at the end division
118
    p1_fmt <= (qfp_x0,regA_i.fmt.sign);
119
    p1_rem <= to_unsigned(0,35);
120
    case rega_i.fmt.exp is
121
      when qfp_x24 => p1_rem <= to_unsigned(1,35);  -- -5
122
      when qfp_x16 => p1_rem <= to_unsigned(2**8,35);  -- +3
123
      when qfp_x8 => p1_rem <= to_unsigned(2**16,35);  -- +11
124
      when qfp_x0 =>
125
        if p1_mant <= to_unsigned(2**3,29) then  -- less or equal than 1/2M
126
          p1_rem <= to_unsigned(1,35); -- -5 
127
          p1_fmt.exp <= qfp_x24;
128
        elsif p1_mant <= to_unsigned(2**11,29) then  -- less or equal than 1/32
129
          p1_rem <= to_unsigned(2**8,35);-- +3
130
          p1_fmt.exp <= qfp_x16;
131
        elsif p1_mant <= to_unsigned(2**19,29) then  -- less or equal than 1/8192
132
          p1_rem <= to_unsigned(2**16,35);-- +11
133
          p1_fmt.exp <= qfp_x8;
134
        else
135
          p1_rem <= to_unsigned(2**24,35);-- +19
136
          p1_fmt.exp <= qfp_x0;
137
        end if;
138
      when others => null;
139
    end case;
140
 
141
    -- stage 2
142
 
143
    -- shift
144
    p2_rem_shft <= p2_rem(33 downto 0) & '0';
145
    p2_quo_shft <= p2_quo(28 downto 0) & '0';
146
 
147
    -- use only upper 30bits for sub, cause last 5bits only appended for not shifting mant
148
    p2_sub <= p2_rem_shft(34 downto 5)-('0' & p2_mant);
149
 
150
    p2_rem_next <= p2_rem_shft;
151
    p2_quo_next <= p2_quo_shft;
152
 
153
    if p2_sub(29) = '0' then           -- overflow: p2_rem_shft >= p2_mant therefore do sub
154
      p2_rem_next(34 downto 5) <= p2_sub;
155
      p2_quo_next(0) <= '1';
156
    end if;
157
 
158
  end process;
159
 
160
  p2_complete <= '1' when p2_cnt = to_unsigned(0,5) else '0';
161
 
162
  ready_o <= not p2_busy;
163
  result_o <= (p2_quo(29 downto 1) & '0' & (22 downto 0 => '0'),to_unsigned(0,5),'0' & p2_fmt.exp,p2_fmt.sign);
164
  complete_o <= p2_complete_1d;
165
 
166
end Rtl;
167
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.